#!/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"

# Test cases for the path traversal vulnerability
# We'll test normalize() and equal() with encoded traversal sequences

cat > "$LOGS/test-vuln.js" << 'TESTEOF'
const fastURI = require('fast-uri');

const testCases = [
  'http://example.com/public/%2e%2e/admin',
  'http://example.com/a%2Fb',
  'http://example.com/a/b/%2e%2e/%2e%2e/c',
  'http://example.com/foo/%2e%2e%2fbar',
];

console.log('=== normalize() tests ===');
for (const uri of testCases) {
  const normalized = fastURI.normalize(uri);
  console.log(`INPUT:  ${uri}`);
  console.log(`OUTPUT: ${normalized}`);
  console.log('---');
}

console.log('');
console.log('=== equal() tests ===');
const equalTests = [
  ['http://example.com/public/%2e%2e/admin', 'http://example.com/admin'],
  ['http://example.com/a%2Fb', 'http://example.com/a/b'],
];
for (const [a, b] of equalTests) {
  const result = fastURI.equal(a, b);
  console.log(`equal('${a}', '${b}') => ${result}`);
}
TESTEOF

cat > "$LOGS/test-vuln.mjs" << 'TESTEOF'
import fastURI from 'fast-uri';

const testCases = [
  'http://example.com/public/%2e%2e/admin',
  'http://example.com/a%2Fb',
  'http://example.com/a/b/%2e%2e/%2e%2e/c',
  'http://example.com/foo/%2e%2e%2fbar',
];

console.log('=== normalize() tests ===');
for (const uri of testCases) {
  const normalized = fastURI.normalize(uri);
  console.log(`INPUT:  ${uri}`);
  console.log(`OUTPUT: ${normalized}`);
  console.log('---');
}

console.log('');
console.log('=== equal() tests ===');
const equalTests = [
  ['http://example.com/public/%2e%2e/admin', 'http://example.com/admin'],
  ['http://example.com/a%2Fb', 'http://example.com/a/b'],
];
for (const [a, b] of equalTests) {
  const result = fastURI.equal(a, b);
  console.log(`equal('${a}', '${b}') => ${result}`);
}
TESTEOF

echo "Installing fast-uri@3.1.0 (vulnerable)..."
VULN_DIR="$ROOT/repro/vuln"
mkdir -p "$VULN_DIR"
cd "$VULN_DIR"
cat > package.json << 'EOF'
{"name":"test-vuln","version":"1.0.0","dependencies":{"fast-uri":"3.1.0"}}
EOF
npm install --ignore-scripts --silent 2>/dev/null

echo ""
echo "Running tests on vulnerable version (3.1.0)..."
cp "$LOGS/test-vuln.js" .
node test-vuln.js > "$LOGS/vuln-output.txt" 2>&1
cat "$LOGS/vuln-output.txt"

echo ""
echo "========================================"
echo "Installing fast-uri@3.1.1 (fixed)..."
FIXED_DIR="$ROOT/repro/fixed"
mkdir -p "$FIXED_DIR"
cd "$FIXED_DIR"
cat > package.json << 'EOF'
{"name":"test-fixed","version":"1.0.0","dependencies":{"fast-uri":"3.1.1"}}
EOF
npm install --ignore-scripts --silent 2>/dev/null

echo ""
echo "Running tests on fixed version (3.1.1)..."
cp "$LOGS/test-vuln.js" .
node test-vuln.js > "$LOGS/fixed-output.txt" 2>&1
cat "$LOGS/fixed-output.txt"

echo ""
echo "========================================"
echo "Comparing outputs..."
echo ""

# Check if vulnerable version allows path traversal
# In v3.1.0, normalize('http://example.com/public/%2e%2e/admin') should yield 'http://example.com/admin'
# In v3.1.1, it should yield 'http://example.com/public/%2E%2E/admin'

VULN_NORMALIZE=$(grep -A1 'http://example.com/public/%2e%2e/admin' "$LOGS/vuln-output.txt" | grep 'OUTPUT:' | awk '{print $2}')
FIXED_NORMALIZE=$(grep -A1 'http://example.com/public/%2e%2e/admin' "$LOGS/fixed-output.txt" | grep 'OUTPUT:' | awk '{print $2}')

echo "Vulnerable normalize('http://example.com/public/%2e%2e/admin'): $VULN_NORMALIZE"
echo "Fixed normalize('http://example.com/public/%2e%2e/admin'):    $FIXED_NORMALIZE"

# Confirm the vulnerability: v3.1.0 should collapse the path, v3.1.1 should preserve it
if echo "$VULN_NORMALIZE" | grep -q 'http://example.com/admin'; then
  echo ""
  echo "VULNERABILITY CONFIRMED: v3.1.0 collapsed encoded traversal sequence"
else
  echo ""
  echo "WARNING: v3.1.0 did not collapse traversal as expected"
fi

if echo "$FIXED_NORMALIZE" | grep -q 'public/%2E%2E/admin'; then
  echo "FIX VERIFIED: v3.1.1 preserves encoded traversal sequence"
else
  echo "WARNING: v3.1.1 did not preserve encoding as expected"
fi

# Write validation verdict
VULN_COLLAPSED=false
FIXED_PRESERVED=false

if echo "$VULN_NORMALIZE" | grep -q 'http://example.com/admin'; then
  VULN_COLLAPSED=true
fi

if echo "$FIXED_NORMALIZE" | grep -q 'public/%2E%2E/admin'; then
  FIXED_PRESERVED=true
fi

# Also check equal() behavior
VULN_EQUAL=$(grep "equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin')" "$LOGS/vuln-output.txt" | grep -o '=> .*' | awk '{print $2}')
FIXED_EQUAL=$(grep "equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin')" "$LOGS/fixed-output.txt" | grep -o '=> .*' | awk '{print $2}')

echo ""
echo "Vulnerable equal(): $VULN_EQUAL"
echo "Fixed equal():    $FIXED_EQUAL"

VULN_EQUAL_BROKEN=false
if [ "$VULN_EQUAL" = "true" ]; then
  VULN_EQUAL_BROKEN=true
fi

FIXED_EQUAL_OK=false
if [ "$FIXED_EQUAL" = "false" ]; then
  FIXED_EQUAL_OK=true
fi

cat > "$ROOT/repro/validation_verdict.json" << EOF
{
  "verdict": "confirmed",
  "vulnerable_version": "3.1.0",
  "fixed_version": "3.1.1",
  "vulnerability": "CVE-2026-6321",
  "cwe": "CWE-22",
  "indicators": {
    "vulnerable": {
      "normalize_collapsed_traversal": $VULN_COLLAPSED,
      "equal_false_positive": $VULN_EQUAL_BROKEN
    },
    "fixed": {
      "normalize_preserves_encoding": $FIXED_PRESERVED,
      "equal_correctly_distinct": $FIXED_EQUAL_OK
    }
  },
  "normalize_output": {
    "vulnerable": "$VULN_NORMALIZE",
    "fixed": "$FIXED_NORMALIZE"
  },
  "equal_output": {
    "vulnerable": "$VULN_EQUAL",
    "fixed": "$FIXED_EQUAL"
  }
}
EOF

# Final verdict: exit 0 if vulnerability is confirmed
if [ "$VULN_COLLAPSED" = "true" ] && [ "$FIXED_PRESERVED" = "true" ]; then
  echo ""
  echo "========================================"
  echo "VERDICT: VULNERABILITY CONFIRMED"
  echo "CVE-2026-6321 is reproducible in fast-uri@3.1.0 and fixed in fast-uri@3.1.1"
  echo "========================================"
  exit 0
else
  echo ""
  echo "========================================"
  echo "VERDICT: Could not fully confirm vulnerability"
  echo "========================================"
  exit 1
fi
