feat(pair-corpus-honesty): add vibe-py, vfc-js and agent-vfc slices with mechanism vocabulary

Tasks 1.1, 5.1, 5.2, 5.4 and the data half of 5.3.

- mechanisms.toml: closed vocabulary v1 (20 ids) every expected row cites.
- vibe-py: 35 Real-Vuln-Benchmark pairs (Apache-2.0), human provenance only
  because the LLM-generated repositories carry no license (escalated).
- vfc-js: 17 Node fix-commit pairs harvested upstream (MIT/Apache-2.0),
  SecBench.js itself is not vendored (no license); sinks derived on 13/17.
- agent-vfc: 29 agent-trailer fixes as catalog-candidates.toml plus
  REVIEW.md; the loaded catalog stays empty until a human reviews them.
- datasets.toml and README document every slice and its review status.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
Marius Ciepluch
2026-09-05 10:45:42 +02:00
co-authored by Claude Fable 5.1
parent c3e841003c
commit 8ab4207618
182 changed files with 31299 additions and 0 deletions
+35
View File
@@ -40,6 +40,41 @@ Pairs in this directory **must not** join `LANGUAGE_MANIFESTS`.
`vfc/training/manifest.jsonl` (vuln vs fixed, one snapshot per line).
Grow with a blobless `git log --grep=CVE-202` mine plus `vfc/harvest.py`,
then `vfc/generate_catalog.py` (maintainer, not CI).
- **vibe-py** — Real-Vuln-Benchmark functions (`benchmarks/pairs/vibe-py/`):
Python web repos pinned by commit, one vulnerable function per pair with a
false-positive trap from the same repo as the fixed twin. Today only the 15
licensed human-authored repos are vendored (`provenance = "human"`); the 40
LLM-generated repos carry no license file and are excluded until one is
stated upstream. Educational/CTF apps, not production. Honesty dashboard.
- **vfc-js** — server-side JavaScript function pairs harvested from the upstream
fix commits that SecBench.js records (`benchmarks/pairs/vfc-js/`). Command
injection, path traversal, and code injection first; prototype pollution and
ReDoS carry their mechanism and may be `known_limit`. No SecBench.js file is
vendored. Honesty dashboard.
- **agent-vfc** — security-fix commits carrying an AI agent co-author trailer or
generation marker, in JavaScript, TypeScript, or Python
(`benchmarks/pairs/agent-vfc/`). `provenance = "agent"`. Rows enter
`catalog.toml` only after a human sets `reviewer` in `recipes.toml`; until
then they sit in `catalog-candidates.toml`, which is never loaded. Honesty dashboard.
## Labels, profiles, and mechanisms
Every `[[pair.expected]]` row names a `mechanism` from the closed vocabulary in
`benchmarks/pairs/mechanisms.toml`; every pair carries `provenance`
(`human|agent|mixed|synthetic`), a declared `split` (`train|holdout`), and an
optional `known_limit` reason. The scorer counts overlay `coverage` records with
a source as detections and as leaks, matches by function when a label names one,
never matches a CWE-only row (`weak_label`), and reports `per_profile`,
`per_mechanism`, `achievable` (known-limit pairs excluded), and `loss`
(parse-failed files, unadjudicated proposals). `ousast pairs --profile agent
--split holdout --json` filters; `--hunter` adds the LLM hunter as a third scorer
when a hunter model is configured. The improve loop rejects a change that
regresses any profile on the holdout split.
Harvest for every slice goes through `benchmarks/pairs/harvest.py --slice <name>`
(modes `name`, `line_range`, `hunk`, `enclosing`; comment and string mentions
never anchor) and `benchmarks/pairs/catalog_gen.py --slice <name>` regenerates
the catalog from `recipes.toml`. Maintainer only; CI never fetches.
## Commands
+18
View File
@@ -0,0 +1,18 @@
# agent-vfc slice
Security-fix commits carrying an AI coding agent co-author trailer or generation marker
(Claude Code, Codex, Cursor, Copilot, Devin), in JavaScript, TypeScript, or Python.
`provenance = "agent"`. Only repositories with a stated license are vendored.
## Review checklist (Req 5.3)
A recipe with `reviewer = "pending"` is a candidate, not a label. Before setting `reviewer`:
1. The parent excerpt really contains the vulnerability the title claims (not a refactor).
2. One mechanism from `benchmarks/pairs/mechanisms.toml` explains it; adjust `mechanism` and `cwe`.
3. The fixed excerpt removes it and the change is inside the vendored function.
4. No secret, token, or personal data is in either excerpt (run the redaction check).
5. The license header is present and matches the repository license.
Rebuild: `python benchmarks/pairs/agent-vfc/build_recipes.py --search /tmp/agents.jsonl` then
`--from /tmp/agents.jsonl`, `harvest.py --slice agent-vfc --all --fetch`, `catalog_gen.py --slice agent-vfc`.
+45
View File
@@ -0,0 +1,45 @@
# agent-vfc candidate review sheet
Set `reviewer = "<name>"` in `recipes.toml` for each row you confirm (and fix `mechanism`/`cwe` if the title-based guess is wrong), then run `python benchmarks/pairs/catalog_gen.py --slice agent-vfc`. Rows without a reviewer stay in `catalog-candidates.toml` and are never scored.
| # | name | mechanism (guess) | cwe | language | commit | title |
|---|------|-------------------|-----|----------|--------|-------|
| 1 | `academic-based-qoder-app-a79ddb` | permissive_default | CWE-16 | python | [a79ddb90](https://github.com/1173591564/academic-based-qoder/commit/a79ddb90def54e91f7507cbf6b1548b224d642aa) | fix(hub): allow DSH token validation CORS |
| 2 | `anastasios-pw-session-14ec1a` | source_reaches_sink | CWE-918 | typescript | [14ec1ac5](https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4) | fix(browser): harden SSRF redirect guard against non-navigation document hops [A |
| 3 | `arsnova-eu-httpcors-9bcba4` | permissive_default | CWE-16 | typescript | [9bcba4f4](https://github.com/kqc-real/arsnova.eu/commit/9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df) | fix(security): Produktions-CORS auf Same-Origin begrenzen (#143) |
| 4 | `astroclaw-pw-session-1553a8` | source_reaches_sink | CWE-918 | typescript | [1553a8ad](https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b) | fix(browser): harden SSRF redirect guard against non-navigation document hops [A |
| 5 | `capgo-app-apptabs-7d73fd` | permissive_default | CWE-16 | typescript | [7d73fd21](https://github.com/Cap-go/capgo.app/commit/7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7) | fix(notifications): harden API CORS and mark console tab as beta (#2623) |
| 6 | `capgo-app-hono-4dadd2` | permissive_default | CWE-16 | typescript | [4dadd258](https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59) | fix(api): CORS for Capacitor localhost WebView (#3105) |
| 7 | `dailyforge-server-ed1470` | permissive_default | CWE-16 | javascript | [ed147081](https://github.com/Annamdevula-Nissi-Grace/Dailyforge/commit/ed1470814a108bd725c8b27bd9d86cf95a979a96) | Fix: add localhost fallback for CORS origin (#172) |
| 8 | `dnf-plugin-anyrepo-config-26d19a` | path_join_user_input | CWE-22 | python | [26d19aeb](https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0) | fix(config): prevent path traversal in repository names |
| 9 | `edutrace-page-ee7ba2` | prototype_pollution | CWE-1321 | typescript | [ee7ba25f](https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739) | fix(front): impedir prototype pollution nos handlers de formulário aninhado |
| 10 | `etoj-index-605274` | permissive_default | CWE-16 | typescript | [6052743d](https://github.com/Eternity-Sky/_ETOJ/commit/6052743d477eeff62e32553c2790785d3f52c641) | Fix CORS: Add PATCH method to allowed methods |
| 11 | `etude-lexical-markdown-editorconfig-c61a8b` | prototype_pollution | CWE-1321 | typescript | [c61a8bf7](https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed) | fix: guard deepMergeInto against prototype pollution |
| 12 | `etude-lexical-markdown-editorconfig-db4f54` | prototype_pollution | CWE-1321 | typescript | [db4f54b1](https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999) | fix: make prototype pollution guard recognizable by CodeQL |
| 13 | `gitim-git-cors-proxy-e4c3a4` | permissive_default | CWE-16 | typescript | [e4c3a479](https://github.com/CiferaTeam/GitIM/commit/e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6) | fix(frontend): use gitim cors proxy by default |
| 14 | `lensops-kubernetesmanagement-fe4910` | missing_auth_guard | CWE-862 | typescript | [fe49109a](https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84) | Fix missing auth header on namespaces API call |
| 15 | `market-cap-route-4f8ae9` | source_reaches_sink | CWE-601 | typescript | [4f8ae9be](https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6) | Fix open redirects on the auth next param |
| 16 | `melodix-playerprovider-089931` | permissive_default | CWE-16 | typescript | [089931ef](https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13) | Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors |
| 17 | `mercado-do-vale-news-catalogmetadataservice-9b5fcf` | permissive_default | CWE-16 | typescript | [9b5fcf2d](https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598) | fix(catalog): avoid metadata cors preflight |
| 18 | `money-track-category-icons-4d4a5b` | prototype_pollution | CWE-1321 | typescript | [4d4a5b06](https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0) | fix(category-icons): use Object.hasOwn to prevent prototype pollution in type gu |
| 19 | `nestjs-filter-normalizer-aa0e60` | prototype_pollution | CWE-1321 | typescript | [aa0e600d](https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8) | fix(core): add prototype pollution guard to normalizeInput |
| 20 | `new-erp-final-app-6e9644` | permissive_default | CWE-16 | typescript | [6e9644c8](https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59) | fix: allow patch requests through cors |
| 21 | `nimestream-route-d17f53` | source_reaches_sink | CWE-918 | javascript | [d17f535b](https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43) | fix: resolve command injection and SSRF/Open Redirect security issues in multiSc |
| 22 | `onlook-helper-57ce1c` | missing_auth_guard | CWE-862 | typescript | [57ce1ccf](https://github.com/zhcndoc/onlook/commit/57ce1ccfacc7e8484cae59013a2b1e34518560e5) | Fix CVE-2025-63783: Add authorization checks to project mutation APIs (#3062) |
| 23 | `openniw-jobs-0fc947` | identity_from_request_body | CWE-639 | python | [0fc94733](https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10) | Fix IDOR on job endpoint: case-bound jobs require case ownership |
| 24 | `openniw-jobs-b74de3` | identity_from_request_body | CWE-639 | python | [b74de31b](https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68) | Fix IDOR on job endpoint: case-bound jobs require case ownership |
| 25 | `overleaf-with-claude-exportscontroller-3980b9` | identity_from_request_body | CWE-639 | javascript | [3980b9e5](https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431) | Fix IDOR in exports by adding token verification (Issue #31637) (#32883) |
| 26 | `popmark-editorconfig-e5ac40` | prototype_pollution | CWE-1321 | typescript | [e5ac407c](https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb) | fix: guard deepMergeInto against prototype pollution |
| 27 | `rag-pipeline-utils-config-handler-76e5f0` | prototype_pollution | CWE-1321 | javascript | [76e5f0a9](https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7) | fix(security): prevent prototype pollution in config-handler |
| 28 | `registry-proxy-worker-426847` | permissive_default | CWE-16 | javascript | [42684789](https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8) | fix: handle CORS OPTIONS preflight for catalog fetches (#10) |
| 29 | `rls-alembic-rls-d2b6af` | permissive_default | CWE-16 | python | [d2b6af47](https://github.com/DelfinaCare/rls/commit/d2b6af47347fb285b7a3820a7f2d5dded20907ec) | Guard against ENABLE ROW LEVEL SECURITY on tables with no policies (#143) |
| 30 | `supplieradvisor-mvp-route-387bcf` | identity_from_request_body | CWE-639 | typescript | [387bcf40](https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8) | Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156) |
| 31 | `supplieradvisor-mvp-route-a69e8f` | identity_from_request_body | CWE-639 | typescript | [a69e8f27](https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1) | Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership |
| 32 | `tools-cli-tools-a96bc0` | source_reaches_sink | CWE-78 | python | [a96bc050](https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a) | 🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307) |
| 33 | `tools-wsgi-e18686` | path_join_user_input | CWE-22 | python | [e18686aa](https://github.com/D-sorganization/Tools/commit/e18686aaa174a8a4843c07b4727771c92e0f179e) | fix(security): validate mesh filenames against path traversal in _download_meshe |
| 34 | `trackly-cli-path-diagnostics-1c1aed` | path_join_user_input | CWE-22 | javascript | [1c1aed89](https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6) | fix(apply): report blocked path traversal |
| 35 | `upstreamdrift-local-server-c3a078` | path_join_user_input | CWE-22 | python | [c3a07870](https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b) | fix(api): harden local server path traversal (#2805) (#2839) |
| 36 | `vantalk-firebase-16c3b0` | secret_in_client | CWE-798 | typescript | [16c3b028](https://github.com/NiSeullent/VanTalk/commit/16c3b02875b1f51c3cac1dc185e199978a35985c) | fix(security): load Firebase API key from env, remove hardcoded secret |
| 37 | `waggledance-swarm-ssrf-host-guard-9a4548` | source_reaches_sink | CWE-918 | python | [9a454843](https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b) | fix(ssrf): reject bare-string allowed hosts (#1460) |
| 38 | `workers-research-utils-209444` | source_reaches_sink | CWE-89 | typescript | [209444eb](https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e) | Fix SQL injection in search by using parameterized queries (#41) |
| 39 | `zoonk-origin-bfbf67` | permissive_default | CWE-16 | typescript | [bfbf670c](https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31) | fix(api): allow staging cors from previews (#1559) |
@@ -0,0 +1,38 @@
// Provenance: Anas329796/Anastasios (fixed).
// repo: Anas329796/Anastasios
// commit: 14ec1ac50f9e4e255d875236d30129c6207401d4
// parent: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
// commit_url: https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4
// cve:
// license: MIT
// function: isTopLevelNavigationRequest
// relpath: extensions/browser/src/browser/pw-session.ts
// provenance: agent
// mechanism: source_reaches_sink
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
let sameMainFrame = false;
try {
sameMainFrame = request.frame() === page.mainFrame();
} catch {
// Frame resolution can fail during redirect/renderer churn; fail closed.
sameMainFrame = true;
}
if (!sameMainFrame) {
return false;
}
try {
if (request.isNavigationRequest()) {
return true;
}
} catch {
// Ignore and fall back to resource-type check below.
}
try {
return request.resourceType() === "document";
} catch {
return false;
}
}
@@ -0,0 +1,22 @@
// Provenance: Anas329796/Anastasios (vuln).
// repo: Anas329796/Anastasios
// commit: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
// parent: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
// commit_url: https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4
// cve:
// license: MIT
// function: isTopLevelNavigationRequest
// relpath: extensions/browser/src/browser/pw-session.ts
// provenance: agent
// mechanism: source_reaches_sink
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
if (!request.isNavigationRequest()) {
return false;
}
try {
return request.frame() === page.mainFrame();
} catch {
return true;
}
}
@@ -0,0 +1,38 @@
// Provenance: P1R4N351/astroclaw (fixed).
// repo: P1R4N351/astroclaw
// commit: 1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
// parent: d3eed2dc01328f21dd404477bb28e2740fa371a4
// commit_url: https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
// cve:
// license: MIT
// function: isTopLevelNavigationRequest
// relpath: extensions/browser/src/browser/pw-session.ts
// provenance: agent
// mechanism: source_reaches_sink
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
let sameMainFrame = false;
try {
sameMainFrame = request.frame() === page.mainFrame();
} catch {
// Frame resolution can fail during redirect/renderer churn; fail closed.
sameMainFrame = true;
}
if (!sameMainFrame) {
return false;
}
try {
if (request.isNavigationRequest()) {
return true;
}
} catch {
// Ignore and fall back to resource-type check below.
}
try {
return request.resourceType() === "document";
} catch {
return false;
}
}
@@ -0,0 +1,22 @@
// Provenance: P1R4N351/astroclaw (vuln).
// repo: P1R4N351/astroclaw
// commit: d3eed2dc01328f21dd404477bb28e2740fa371a4
// parent: d3eed2dc01328f21dd404477bb28e2740fa371a4
// commit_url: https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
// cve:
// license: MIT
// function: isTopLevelNavigationRequest
// relpath: extensions/browser/src/browser/pw-session.ts
// provenance: agent
// mechanism: source_reaches_sink
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
if (!request.isNavigationRequest()) {
return false;
}
try {
return request.frame() === page.mainFrame();
} catch {
return true;
}
}
+253
View File
@@ -0,0 +1,253 @@
#!/usr/bin/env python3
"""Build agent-vfc candidate recipes from agent-authored security-fix commits (maintainer, network via gh).
Candidates come from GitHub commit search on agent co-author trailers or generation
markers plus security-fix wording (see --search). Each candidate is kept only when the
repository states a license, the fix touches one to three JavaScript, TypeScript, or
Python files, and the largest changed file has at most --max-lines changed lines.
Every recipe starts with ``reviewer = "pending"``; a human must set the reviewer and
confirm the mechanism before the pair is trusted (Req 5.3).
python benchmarks/pairs/agent-vfc/build_recipes.py --search /tmp/agent_candidates.jsonl
python benchmarks/pairs/agent-vfc/build_recipes.py --from /tmp/agent_candidates.jsonl
python benchmarks/pairs/harvest.py --slice agent-vfc --all --fetch
python benchmarks/pairs/catalog_gen.py --slice agent-vfc
"""
from __future__ import annotations
import argparse
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parent
TRAILERS = (
'"Co-Authored-By: Claude"',
'"Generated with Claude Code"',
'"Co-authored-by: Cursor"',
'"Co-authored-by: Codex"',
'"Co-authored-by: Copilot"',
'"Co-authored-by: devin"',
)
KEYWORDS = (
'"fix IDOR"',
'"SQL injection"',
'"path traversal"',
"SSRF",
'"hardcoded secret"',
'"CORS"',
'"row level security"',
'"authorization check"',
'"command injection"',
'"prototype pollution"',
'"open redirect"',
'"missing authentication"',
)
MECHANISM_BY_TITLE = (
(
re.compile(r"\bidor\b|ownership|owner.?scope|user_id from|tenant", re.I),
"identity_from_request_body",
"CWE-639",
"insecure direct object reference",
),
(
re.compile(r"missing auth|unauthenticated|auth(?:orization|entication)? (?:check|guard|middleware)|require.?auth", re.I),
"missing_auth_guard",
"CWE-862",
"missing authorization",
),
(re.compile(r"sql injection|sqli", re.I), "source_reaches_sink", "CWE-89", "sql injection"),
(re.compile(r"path traversal|zip slip|directory traversal", re.I), "path_join_user_input", "CWE-22", "path traversal"),
(re.compile(r"\bssrf\b", re.I), "source_reaches_sink", "CWE-918", "server-side request forgery"),
(re.compile(r"command injection|shell injection", re.I), "source_reaches_sink", "CWE-78", "command injection"),
(re.compile(r"prototype pollution", re.I), "prototype_pollution", "CWE-1321", "prototype pollution"),
(re.compile(r"open redirect", re.I), "source_reaches_sink", "CWE-601", "open redirect"),
(
re.compile(r"hardcoded|hard-coded|leaked (?:key|secret|token)|service.?role", re.I),
"secret_in_client",
"CWE-798",
"hardcoded credentials",
),
(re.compile(r"\bcors\b|row level security|\brls\b|debug", re.I), "permissive_default", "CWE-16", "permissive default"),
)
ACCEPTED_LICENSES = {
"MIT",
"Apache-2.0",
"BSD-3-Clause",
"BSD-2-Clause",
"ISC",
"MPL-2.0",
"GPL-3.0",
"GPL-2.0",
"AGPL-3.0",
"Unlicense",
"0BSD",
}
_CODE = re.compile(r"\.(py|js|mjs|cjs|ts|tsx)$")
_SKIP = re.compile(r"(test|spec|\.d\.ts|migration|dist/|build/|min\.js|\.config\.|stories)", re.I)
_NOISE = re.compile(r"\b(css|icon|i18n|layout|docs?|tracker|sess[aã]o|chore|bump|migration|workflow)\b", re.I)
def _gh(args: list[str]) -> object:
return json.loads(subprocess.check_output(["gh", "api", *args], stderr=subprocess.DEVNULL))
def search(out: Path) -> int:
seen: set[tuple[str, str]] = set()
with out.open("w") as handle:
for trailer in TRAILERS:
for keyword in KEYWORDS:
time.sleep(6) # commit search has a strict secondary rate limit
try:
result = _gh(["-X", "GET", "search/commits", "-f", f"q={trailer} {keyword} fix", "-f", "per_page=30"])
except Exception: # noqa: BLE001 — rate limited; keep going
continue
for item in result.get("items", []) if isinstance(result, dict) else []:
key = (item["repository"]["full_name"], item["sha"])
if key in seen:
continue
seen.add(key)
handle.write(
json.dumps(
{
"repo": key[0],
"sha": key[1],
"title": item["commit"]["message"].split("\n")[0][:160],
"date": item["commit"]["author"]["date"],
}
)
+ "\n"
)
return len(seen)
def classify(title: str) -> tuple[str, str, str] | None:
for pattern, mechanism, cwe, cls in MECHANISM_BY_TITLE:
if pattern.search(title):
return mechanism, cwe, cls
return None
def build(source: Path, *, limit: int, max_lines: int) -> tuple[list[dict[str, object]], dict[str, int]]:
recipes: list[dict[str, object]] = []
skipped = {"noise_title": 0, "unclassified": 0, "unlicensed": 0, "no_code_file": 0, "too_big": 0, "api": 0, "duplicate_repo": 0}
per_repo: dict[str, int] = {}
seen_commits: set[str] = set() # the same fix commit shows up in every fork
rows = [json.loads(line) for line in source.read_text().splitlines() if line.strip()]
for row in sorted(rows, key=lambda r: (r["repo"], r["date"])):
if len(recipes) >= limit:
break
title = str(row["title"])
if _NOISE.search(title):
skipped["noise_title"] += 1
continue
classified = classify(title)
if classified is None:
skipped["unclassified"] += 1
continue
if per_repo.get(row["repo"], 0) >= 2 or row["sha"] in seen_commits:
skipped["duplicate_repo"] += 1
continue
seen_commits.add(row["sha"])
time.sleep(0.8)
try:
info = _gh([f"repos/{row['repo']}"])
commit = _gh([f"repos/{row['repo']}/commits/{row['sha']}"])
except Exception: # noqa: BLE001
skipped["api"] += 1
continue
assert isinstance(info, dict) and isinstance(commit, dict)
license_id = (info.get("license") or {}).get("spdx_id") or ""
if license_id not in ACCEPTED_LICENSES:
skipped["unlicensed"] += 1
continue
files = [f for f in commit.get("files", []) if _CODE.search(f["filename"]) and not _SKIP.search(f["filename"]) and f.get("patch")]
if not files or len(files) > 3:
skipped["no_code_file"] += 1
continue
target = sorted(files, key=lambda f: -(f.get("additions", 0) + f.get("deletions", 0)))[0]
if target.get("additions", 0) + target.get("deletions", 0) > max_lines:
skipped["too_big"] += 1
continue
parents = commit.get("parents") or []
if not parents:
skipped["api"] += 1
continue
mechanism, cwe, cls = classified
message = commit["commit"]["message"]
trailer = next((line.strip() for line in message.splitlines() if re.match(r"(?i)co-authored-by:|generated with", line.strip())), "")
suffix = Path(target["filename"]).suffix
language = {".py": "python", ".ts": "typescript", ".tsx": "typescript"}.get(suffix, "javascript")
base = re.sub(r"[^a-z0-9]+", "-", f"{row['repo'].split('/')[-1]}-{Path(target['filename']).stem}".lower()).strip("-")[:56]
name = f"{base}-{row['sha'][:6]}"
per_repo[row["repo"]] = per_repo.get(row["repo"], 0) + 1
recipes.append(
{
"name": name,
"host": "github",
"repo": row["repo"],
"parent": parents[0]["sha"],
"commit": commit["sha"],
"path": target["filename"],
"mode": "hunk",
"language": language,
"relpath": target["filename"],
"license": license_id,
"cve": "",
"year": int(str(commit["commit"]["author"]["date"])[:4]),
"cwe": cwe,
"class": cls,
"mechanism": mechanism,
"provenance": "agent",
"origin": "github-agent-trailer",
"project": row["repo"].split("/")[-1],
"trailer": trailer[:120],
"reviewer": "pending",
"evidence": title[:200],
"commit_url": f"https://github.com/{row['repo']}/commit/{commit['sha']}",
}
)
for index, recipe in enumerate(sorted(recipes, key=lambda r: str(r["name"]))):
recipe["split"] = "holdout" if index % 2 else "train"
return recipes, skipped
def to_toml(recipes: list[dict[str, object]]) -> str:
lines = [
"# agent-vfc candidate recipes from agent-trailer security-fix commits (build_recipes.py).",
'# reviewer = "pending" means a human has not yet confirmed the vulnerability and mechanism.',
"",
]
for recipe in sorted(recipes, key=lambda r: str(r["name"])):
lines.append("[[recipe]]")
for key, value in recipe.items():
if isinstance(value, int) and not isinstance(value, bool):
lines.append(f"{key} = {value}")
else:
lines.append(f'{key} = "{str(value).replace(chr(92), chr(92) * 2).replace(chr(34), chr(92) + chr(34))}"')
lines.append("")
return "\n".join(lines)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--search", type=Path, help="run the GitHub commit search and write candidates to this jsonl")
parser.add_argument("--from", dest="source", type=Path, help="candidate jsonl to resolve into recipes")
parser.add_argument("--limit", type=int, default=40)
parser.add_argument("--max-lines", type=int, default=80)
parser.add_argument("--out", type=Path, default=ROOT / "recipes.toml")
args = parser.parse_args(argv)
if args.search:
print(f"searched {search(args.search)} candidates -> {args.search}")
if args.source:
recipes, skipped = build(args.source, limit=args.limit, max_lines=args.max_lines)
args.out.write_text(to_toml(recipes), encoding="utf-8")
print(f"wrote {args.out} ({len(recipes)} recipes); skipped {skipped}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,91 @@
// Provenance: Cap-go/capgo.app (fixed).
// repo: Cap-go/capgo.app
// commit: 4dadd2580d02213d227a331eee0232aa59859b59
// parent: 8c0ac7e233946abd8dc26581b871e9fcd0928899
// commit_url: https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59
// cve:
// license: AGPL-3.0
// function: next
// relpath: supabase/functions/_backend/utils/hono.ts
// provenance: agent
// mechanism: permissive_default
export function createHono(functionName: string, _version: string) {
let appGlobal
if (getRuntimeKey() === 'deno') {
appGlobal = new Hono<MiddlewareKeyVariables>().basePath(`/${functionName}`)
}
else {
appGlobal = new Hono<MiddlewareKeyVariables>()
}
// Plugin hot paths (/updates|/stats|/channel_self and the CF plugin worker).
// HAR/CPU inspect showed middleware + logging dominating non-DB request cost.
const pluginHotPath = functionName === 'plugin'
|| functionName === 'updates'
|| functionName === 'stats'
|| functionName === 'channel_self'
appGlobal.use('*', (c, next): Promise<any> => {
// ADD HEADER TO IDENTIFY WORKER SOURCE
const name = `${getEnv(c, 'ENV_NAME') || functionName}-${CapgoVersion}`
c.header('X-Worker-Source', name)
const hostname = new URL(c.req.url).hostname
if (!isPreviewHost(hostname))
c.header('Content-Security-Policy', API_CONTENT_SECURITY_POLICY)
return next()
})
// Echo ACAO after the handler so Capacitor WebView origins work on routes
// that forgot useCors (GET /ok). Do not mount hono cors globally: it
// short-circuits OPTIONS and strips TUS discovery headers.
if (!pluginHotPath) {
appGlobal.use('*', async (c, next) => {
await next()
const origin = c.req.header('origin')
if (!origin)
return
const allowed = getAllowedCorsOrigin(origin, c)
if (allowed) {
c.header('Access-Control-Allow-Origin', allowed)
c.header('Vary', 'Origin', { append: true })
}
})
}
// Skip hono's access logger on plugin hot paths — it serializes every request
// on millions of device calls/day.
if (!pluginHotPath)
appGlobal.use('*', logger())
// Use platform-specific request IDs, fallback to generated UUID.
// Do not cloudlog inside the generator: it runs on every request (incl. cf-ray).
appGlobal.use('*', requestId({
generator: (c) => {
// Cloudflare provides the Ray ID in the cf-ray header
// Check this first as it's our primary deployment target
const cfRay = c.req.header('cf-ray')
if (cfRay)
return cfRay
// Supabase Edge Functions provide SB_EXECUTION_ID
const sbExecutionId = getEnv(c, 'SB_EXECUTION_ID')
if (sbExecutionId)
return sbExecutionId
// Fallback to crypto.randomUUID() if not on any known platform
return crypto.randomUUID()
},
}))
appGlobal.post('/ok', (c) => {
return c.json(BRES)
})
appGlobal.post('/ko', (c) => {
const defaultResponse: SimpleErrorResponse = {
error: 'unknown_error',
message: 'KO',
moreInfo: {},
}
return c.json(defaultResponse, 500)
})
return appGlobal
}
@@ -0,0 +1,74 @@
// Provenance: Cap-go/capgo.app (vuln).
// repo: Cap-go/capgo.app
// commit: 8c0ac7e233946abd8dc26581b871e9fcd0928899
// parent: 8c0ac7e233946abd8dc26581b871e9fcd0928899
// commit_url: https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59
// cve:
// license: AGPL-3.0
// function: next
// relpath: supabase/functions/_backend/utils/hono.ts
// provenance: agent
// mechanism: permissive_default
export function createHono(functionName: string, _version: string) {
let appGlobal
if (getRuntimeKey() === 'deno') {
appGlobal = new Hono<MiddlewareKeyVariables>().basePath(`/${functionName}`)
}
else {
appGlobal = new Hono<MiddlewareKeyVariables>()
}
// Plugin hot paths (/updates|/stats|/channel_self and the CF plugin worker).
// HAR/CPU inspect showed middleware + logging dominating non-DB request cost.
const pluginHotPath = functionName === 'plugin'
|| functionName === 'updates'
|| functionName === 'stats'
|| functionName === 'channel_self'
appGlobal.use('*', (c, next): Promise<any> => {
// ADD HEADER TO IDENTIFY WORKER SOURCE
const name = `${getEnv(c, 'ENV_NAME') || functionName}-${CapgoVersion}`
c.header('X-Worker-Source', name)
const hostname = new URL(c.req.url).hostname
if (!isPreviewHost(hostname))
c.header('Content-Security-Policy', API_CONTENT_SECURITY_POLICY)
return next()
})
// Skip hono's access logger on plugin hot paths — it serializes every request
// on millions of device calls/day.
if (!pluginHotPath)
appGlobal.use('*', logger())
// Use platform-specific request IDs, fallback to generated UUID.
// Do not cloudlog inside the generator: it runs on every request (incl. cf-ray).
appGlobal.use('*', requestId({
generator: (c) => {
// Cloudflare provides the Ray ID in the cf-ray header
// Check this first as it's our primary deployment target
const cfRay = c.req.header('cf-ray')
if (cfRay)
return cfRay
// Supabase Edge Functions provide SB_EXECUTION_ID
const sbExecutionId = getEnv(c, 'SB_EXECUTION_ID')
if (sbExecutionId)
return sbExecutionId
// Fallback to crypto.randomUUID() if not on any known platform
return crypto.randomUUID()
},
}))
appGlobal.post('/ok', (c) => {
return c.json(BRES)
})
appGlobal.post('/ko', (c) => {
const defaultResponse: SimpleErrorResponse = {
error: 'unknown_error',
message: 'KO',
moreInfo: {},
}
return c.json(defaultResponse, 500)
})
return appGlobal
}
@@ -0,0 +1,819 @@
# CANDIDATES awaiting human review (reviewer = "pending"). Not loaded by load_pair_catalog.
# Set `reviewer` in recipes.toml after confirming vulnerability, mechanism, and license; then regenerate.
# agent-vfc pair slice. Reviewed isolated functions with provenance.
# Honesty dashboard — not the local 100% CI gate.
# Do not add these names to LANGUAGE_MANIFESTS.
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
[[pair]]
name = "anastasios-pw-session-14ec1a"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "Anas329796/Anastasios"
cve = ""
cwe = "CWE-918"
commit = "14ec1ac50f9e4e255d875236d30129c6207401d4"
parent = "adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb"
commit_url = "https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4"
vuln = "anastasios-pw-session-14ec1a/vuln.ts"
fixed = "anastasios-pw-session-14ec1a/fixed.ts"
relpath = "extensions/browser/src/browser/pw-session.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-918"
class = "server-side request forgery"
path = "extensions/browser/src/browser/pw-session.ts"
function = "isTopLevelNavigationRequest"
mechanism = "source_reaches_sink"
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
[[pair]]
name = "astroclaw-pw-session-1553a8"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "P1R4N351/astroclaw"
cve = ""
cwe = "CWE-918"
commit = "1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
parent = "d3eed2dc01328f21dd404477bb28e2740fa371a4"
commit_url = "https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
vuln = "astroclaw-pw-session-1553a8/vuln.ts"
fixed = "astroclaw-pw-session-1553a8/fixed.ts"
relpath = "extensions/browser/src/browser/pw-session.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-918"
class = "server-side request forgery"
path = "extensions/browser/src/browser/pw-session.ts"
function = "isTopLevelNavigationRequest"
mechanism = "source_reaches_sink"
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
[[pair]]
name = "capgo-app-hono-4dadd2"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "AGPL-3.0"
repo = "Cap-go/capgo.app"
cve = ""
cwe = "CWE-16"
commit = "4dadd2580d02213d227a331eee0232aa59859b59"
parent = "8c0ac7e233946abd8dc26581b871e9fcd0928899"
commit_url = "https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59"
vuln = "capgo-app-hono-4dadd2/vuln.ts"
fixed = "capgo-app-hono-4dadd2/fixed.ts"
relpath = "supabase/functions/_backend/utils/hono.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "supabase/functions/_backend/utils/hono.ts"
function = "next"
mechanism = "permissive_default"
evidence = "fix(api): CORS for Capacitor localhost WebView (#3105)"
[[pair]]
name = "dnf-plugin-anyrepo-config-26d19a"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "Apache-2.0"
repo = "jfut/dnf-plugin-anyrepo"
cve = ""
cwe = "CWE-22"
commit = "26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
parent = "33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a"
commit_url = "https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
vuln = "dnf-plugin-anyrepo-config-26d19a/vuln.py"
fixed = "dnf-plugin-anyrepo-config-26d19a/fixed.py"
relpath = "dnf_plugin_anyrepo/config.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "dnf_plugin_anyrepo/config.py"
function = "validate_repo_name"
mechanism = "path_join_user_input"
evidence = "fix(config): prevent path traversal in repository names"
[[pair]]
name = "edutrace-page-ee7ba2"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "Apache-2.0"
repo = "jardimdesoftware/edutrace"
cve = ""
cwe = "CWE-1321"
commit = "ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
parent = "c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd"
commit_url = "https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
vuln = "edutrace-page-ee7ba2/vuln.tsx"
fixed = "edutrace-page-ee7ba2/fixed.tsx"
relpath = "front/src/app/editar-anamnese/page.tsx"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "front/src/app/editar-anamnese/page.tsx"
function = "handleInputChange"
mechanism = "prototype_pollution"
evidence = "fix(front): impedir prototype pollution nos handlers de formulário aninhado"
[[pair]]
name = "etude-lexical-markdown-editorconfig-c61a8b"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "dayflower/etude-lexical-markdown"
cve = ""
cwe = "CWE-1321"
commit = "c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
parent = "0a2184f59e79a04b1365cd49200026e8f2ffdbd5"
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
vuln = "etude-lexical-markdown-editorconfig-c61a8b/vuln.ts"
fixed = "etude-lexical-markdown-editorconfig-c61a8b/fixed.ts"
relpath = "src/config/editorConfig.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "src/config/editorConfig.ts"
function = "deepMergeInto"
mechanism = "prototype_pollution"
evidence = "fix: guard deepMergeInto against prototype pollution"
[[pair]]
name = "etude-lexical-markdown-editorconfig-db4f54"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "dayflower/etude-lexical-markdown"
cve = ""
cwe = "CWE-1321"
commit = "db4f54b1ab80ad596de6425e84f90aa781c49999"
parent = "1c865815d05b072f4973388c3ac66b6696d9efde"
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999"
vuln = "etude-lexical-markdown-editorconfig-db4f54/vuln.ts"
fixed = "etude-lexical-markdown-editorconfig-db4f54/fixed.ts"
relpath = "src/config/editorConfig.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "src/config/editorConfig.ts"
function = "deepMergeInto"
mechanism = "prototype_pollution"
evidence = "fix: make prototype pollution guard recognizable by CodeQL"
[[pair]]
name = "lensops-kubernetesmanagement-fe4910"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "amitknigam84/lensops"
cve = ""
cwe = "CWE-862"
commit = "fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
parent = "9b87ecc3a44a7fe2a5185cca1fe52441647d5748"
commit_url = "https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
vuln = "lensops-kubernetesmanagement-fe4910/vuln.tsx"
fixed = "lensops-kubernetesmanagement-fe4910/fixed.tsx"
relpath = "components/KubernetesManagement.tsx"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-862"
class = "missing authorization"
path = "components/KubernetesManagement.tsx"
function = "setErrorMessage"
mechanism = "missing_auth_guard"
evidence = "Fix missing auth header on namespaces API call"
[[pair]]
name = "market-cap-route-4f8ae9"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "navaneethbv/market-cap"
cve = ""
cwe = "CWE-601"
commit = "4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
parent = "fec6f024ce72c9c47b61cbac6ce7a35cb2280602"
commit_url = "https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
vuln = "market-cap-route-4f8ae9/vuln.ts"
fixed = "market-cap-route-4f8ae9/fixed.ts"
relpath = "app/auth/confirm/route.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-601"
class = "open redirect"
path = "app/auth/confirm/route.ts"
function = "GET"
mechanism = "source_reaches_sink"
evidence = "Fix open redirects on the auth next param"
[[pair]]
name = "melodix-playerprovider-089931"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "alexshao3/melodix"
cve = ""
cwe = "CWE-16"
commit = "089931ef71ea1e5b7586520baf1a5498e2f05b13"
parent = "c074fc7413338aefcbea3170ef4d3ba486a8a4b7"
commit_url = "https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13"
vuln = "melodix-playerprovider-089931/vuln.tsx"
fixed = "melodix-playerprovider-089931/fixed.tsx"
relpath = "apps/miniapp/src/components/PlayerProvider.tsx"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "apps/miniapp/src/components/PlayerProvider.tsx"
function = "PlayerProvider"
mechanism = "permissive_default"
evidence = "Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors"
[[pair]]
name = "mercado-do-vale-news-catalogmetadataservice-9b5fcf"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "handielson/Mercado-do-vale-news"
cve = ""
cwe = "CWE-16"
commit = "9b5fcf2dae41e56f5f97952266f2d6ba59598598"
parent = "70ca282b819ac1d60f4b5e665d224b1043ff1ccc"
commit_url = "https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598"
vuln = "mercado-do-vale-news-catalogmetadataservice-9b5fcf/vuln.ts"
fixed = "mercado-do-vale-news-catalogmetadataservice-9b5fcf/fixed.ts"
relpath = "services/catalogMetadataService.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "services/catalogMetadataService.ts"
function = "fetchMetadata"
mechanism = "permissive_default"
evidence = "fix(catalog): avoid metadata cors preflight"
[[pair]]
name = "money-track-category-icons-4d4a5b"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "andrebubniak/money-track"
cve = ""
cwe = "CWE-1321"
commit = "4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
parent = "add96df6d6a6b61506635c23dbacf6c6cfe24dc2"
commit_url = "https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
vuln = "money-track-category-icons-4d4a5b/vuln.ts"
fixed = "money-track-category-icons-4d4a5b/fixed.ts"
relpath = "src/lib/category-icons.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "src/lib/category-icons.ts"
function = "isCategoryIcon"
mechanism = "prototype_pollution"
evidence = "fix(category-icons): use Object.hasOwn to prevent prototype pollution in type guard"
[[pair]]
name = "nestjs-filter-normalizer-aa0e60"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "DavideCarvalho/nestjs-filter"
cve = ""
cwe = "CWE-1321"
commit = "aa0e600d05997ea3d77538ea1c2db427c439f2e8"
parent = "d899b40d3466f2ffbe9f01c4d49267412401f078"
commit_url = "https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8"
vuln = "nestjs-filter-normalizer-aa0e60/vuln.ts"
fixed = "nestjs-filter-normalizer-aa0e60/fixed.ts"
relpath = "packages/core/src/input/normalizer.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "packages/core/src/input/normalizer.ts"
function = "normalizeInput"
mechanism = "prototype_pollution"
evidence = "fix(core): add prototype pollution guard to normalizeInput"
[[pair]]
name = "new-erp-final-app-6e9644"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "Apache-2.0"
repo = "Sachin-Salgar/NEW_ERP_FINAL"
cve = ""
cwe = "CWE-16"
commit = "6e9644c81ce3fb356669157182a5ef09a70c4b59"
parent = "08976c5d7a07b0663669b875b4507446199f85d7"
commit_url = "https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59"
vuln = "new-erp-final-app-6e9644/vuln.ts"
fixed = "new-erp-final-app-6e9644/fixed.ts"
relpath = "src/presentation/http/app.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "src/presentation/http/app.ts"
function = "origin"
mechanism = "permissive_default"
evidence = "fix: allow patch requests through cors"
[[pair]]
name = "nimestream-route-d17f53"
slice = "agent-vfc"
language = "javascript"
origin = "github-agent-trailer"
license = "MIT"
repo = "Irnhakim/nimestream"
cve = ""
cwe = "CWE-918"
commit = "d17f535bf3012041b056ff3aa991ff6cfa198e43"
parent = "0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0"
commit_url = "https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43"
vuln = "nimestream-route-d17f53/vuln.js"
fixed = "nimestream-route-d17f53/fixed.js"
relpath = "app/api/img/route.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-918"
class = "server-side request forgery"
path = "app/api/img/route.js"
function = "GET"
mechanism = "source_reaches_sink"
evidence = "fix: resolve command injection and SSRF/Open Redirect security issues in multiScraper and image proxy API"
[[pair]]
name = "openniw-jobs-0fc947"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "MIT"
repo = "HHHHHejia/openniw"
cve = ""
cwe = "CWE-639"
commit = "0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
parent = "4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc"
commit_url = "https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
vuln = "openniw-jobs-0fc947/vuln.py"
fixed = "openniw-jobs-0fc947/fixed.py"
relpath = "backend/app/routers/jobs.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-639"
class = "insecure direct object reference"
path = "backend/app/routers/jobs.py"
function = "get_job"
mechanism = "identity_from_request_body"
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
[[pair]]
name = "openniw-jobs-b74de3"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "MIT"
repo = "ziyuzuo/openniw"
cve = ""
cwe = "CWE-639"
commit = "b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
parent = "98a0c392ba96cd2c4aa746dd6fc2b183f385225e"
commit_url = "https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
vuln = "openniw-jobs-b74de3/vuln.py"
fixed = "openniw-jobs-b74de3/fixed.py"
relpath = "backend/app/routers/jobs.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-639"
class = "insecure direct object reference"
path = "backend/app/routers/jobs.py"
function = "get_job"
mechanism = "identity_from_request_body"
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
[[pair]]
name = "overleaf-with-claude-exportscontroller-3980b9"
slice = "agent-vfc"
language = "javascript"
origin = "github-agent-trailer"
license = "AGPL-3.0"
repo = "ZUENS2020/overleaf-with-claude"
cve = ""
cwe = "CWE-639"
commit = "3980b9e5806defb63e45ae2696e6c1899f3a8431"
parent = "5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed"
commit_url = "https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431"
vuln = "overleaf-with-claude-exportscontroller-3980b9/vuln.mjs"
fixed = "overleaf-with-claude-exportscontroller-3980b9/fixed.mjs"
relpath = "services/web/app/src/Features/Exports/ExportsController.mjs"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-639"
class = "insecure direct object reference"
path = "services/web/app/src/Features/Exports/ExportsController.mjs"
function = "exportProject"
mechanism = "identity_from_request_body"
evidence = "Fix IDOR in exports by adding token verification (Issue #31637) (#32883)"
[[pair]]
name = "popmark-editorconfig-e5ac40"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "dayflower/popmark"
cve = ""
cwe = "CWE-1321"
commit = "e5ac407cef37c37178d440541ede301c838640fb"
parent = "31d1ac79b4cfa3118597348e79800a6561115149"
commit_url = "https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb"
vuln = "popmark-editorconfig-e5ac40/vuln.ts"
fixed = "popmark-editorconfig-e5ac40/fixed.ts"
relpath = "src/lexical-markdown/config/editorConfig.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "src/lexical-markdown/config/editorConfig.ts"
function = "deepMergeInto"
mechanism = "prototype_pollution"
evidence = "fix: guard deepMergeInto against prototype pollution"
[[pair]]
name = "rag-pipeline-utils-config-handler-76e5f0"
slice = "agent-vfc"
language = "javascript"
origin = "github-agent-trailer"
license = "MIT"
repo = "DevilsDev/rag-pipeline-utils"
cve = ""
cwe = "CWE-1321"
commit = "76e5f0a94d6803d0e463d26a61cedb7da90857a7"
parent = "ba587867118f703632ff2dc63c4feb8ad6793420"
commit_url = "https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7"
vuln = "rag-pipeline-utils-config-handler-76e5f0/vuln.js"
fixed = "rag-pipeline-utils-config-handler-76e5f0/fixed.js"
relpath = "src/cli/handlers/config-handler.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-1321"
class = "prototype pollution"
path = "src/cli/handlers/config-handler.js"
function = "handleConfigSet"
mechanism = "prototype_pollution"
evidence = "fix(security): prevent prototype pollution in config-handler"
[[pair]]
name = "registry-proxy-worker-426847"
slice = "agent-vfc"
language = "javascript"
origin = "github-agent-trailer"
license = "MIT"
repo = "agents-repo/registry-proxy"
cve = ""
cwe = "CWE-16"
commit = "426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
parent = "6d5937972510cdb5ebca30607b538fdc2e280094"
commit_url = "https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
vuln = "registry-proxy-worker-426847/vuln.js"
fixed = "registry-proxy-worker-426847/fixed.js"
relpath = "src/worker.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "src/worker.js"
function = "buildUpstreamRequest"
mechanism = "permissive_default"
evidence = "fix: handle CORS OPTIONS preflight for catalog fetches (#10)"
[[pair]]
name = "supplieradvisor-mvp-route-387bcf"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "bigfivefoods/supplieradvisor-mvp"
cve = ""
cwe = "CWE-639"
commit = "387bcf40e984a2ee1832ab7beabf0284c5b627d8"
parent = "a7a9bc260d649ea2e582c07435bfd7d93100647b"
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8"
vuln = "supplieradvisor-mvp-route-387bcf/vuln.ts"
fixed = "supplieradvisor-mvp-route-387bcf/fixed.ts"
relpath = "app/api/customers/claims/route.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-639"
class = "insecure direct object reference"
path = "app/api/customers/claims/route.ts"
function = "PATCH"
mechanism = "identity_from_request_body"
evidence = "Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156)"
[[pair]]
name = "supplieradvisor-mvp-route-a69e8f"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "bigfivefoods/supplieradvisor-mvp"
cve = ""
cwe = "CWE-639"
commit = "a69e8f27c0f4d402573d16f0612b51155bbc46e1"
parent = "8558538471e4fb10856f8d9a17d2be5ab5c4fb9c"
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1"
vuln = "supplieradvisor-mvp-route-a69e8f/vuln.ts"
fixed = "supplieradvisor-mvp-route-a69e8f/fixed.ts"
relpath = "app/api/customers/opportunities/route.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-639"
class = "insecure direct object reference"
path = "app/api/customers/opportunities/route.ts"
function = "GET"
mechanism = "identity_from_request_body"
evidence = "Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership checks) (#148)"
[[pair]]
name = "tools-cli-tools-a96bc0"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "MIT"
repo = "D-sorganization/Tools"
cve = ""
cwe = "CWE-78"
commit = "a96bc0502a3dcdac303e4f0152508886e5c35c0a"
parent = "e735d28b82dd1fbc42c0ae01157b38d1b4c7c864"
commit_url = "https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a"
vuln = "tools-cli-tools-a96bc0/vuln.py"
fixed = "tools-cli-tools-a96bc0/fixed.py"
relpath = "src/shared/python/ai/tools/cli_tools.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "src/shared/python/ai/tools/cli_tools.py"
function = "_is_command_allowed"
mechanism = "source_reaches_sink"
evidence = "🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307)"
[[pair]]
name = "trackly-cli-path-diagnostics-1c1aed"
slice = "agent-vfc"
language = "javascript"
origin = "github-agent-trailer"
license = "MIT"
repo = "trackly-app/trackly-cli"
cve = ""
cwe = "CWE-22"
commit = "1c1aed89b07edb04051830c8f086e02b65e961c6"
parent = "8d240ad8d7fc114c8f941ad956a2fdf32391ff60"
commit_url = "https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6"
vuln = "trackly-cli-path-diagnostics-1c1aed/vuln.js"
fixed = "trackly-cli-path-diagnostics-1c1aed/fixed.js"
relpath = "lib/path-diagnostics.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "lib/path-diagnostics.js"
function = "inspectExistingAncestor"
mechanism = "path_join_user_input"
evidence = "fix(apply): report blocked path traversal"
[[pair]]
name = "upstreamdrift-local-server-c3a078"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "MIT"
repo = "D-sorganization/UpstreamDrift"
cve = ""
cwe = "CWE-22"
commit = "c3a0787080489b30e2ed0abfac03b51e45da184b"
parent = "e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc"
commit_url = "https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b"
vuln = "upstreamdrift-local-server-c3a078/vuln.py"
fixed = "upstreamdrift-local-server-c3a078/fixed.py"
relpath = "src/api/local_server.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "src/api/local_server.py"
function = "_find_logo_file"
mechanism = "path_join_user_input"
evidence = "fix(api): harden local server path traversal (#2805) (#2839)"
[[pair]]
name = "waggledance-swarm-ssrf-host-guard-9a4548"
slice = "agent-vfc"
language = "python"
origin = "github-agent-trailer"
license = "Apache-2.0"
repo = "Ahkeratmehilaiset/waggledance-swarm"
cve = ""
cwe = "CWE-918"
commit = "9a454843aa35332ff2eb3106023eee0c4b5e444b"
parent = "934b939f1cca5259eaf807db3319eb97b90d8d80"
commit_url = "https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b"
vuln = "waggledance-swarm-ssrf-host-guard-9a4548/vuln.py"
fixed = "waggledance-swarm-ssrf-host-guard-9a4548/fixed.py"
relpath = "waggledance/core/v3_13_0/ssrf_host_guard.py"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-918"
class = "server-side request forgery"
path = "waggledance/core/v3_13_0/ssrf_host_guard.py"
function = "normalize_allowed_hosts"
mechanism = "source_reaches_sink"
evidence = "fix(ssrf): reject bare-string allowed hosts (#1460)"
[[pair]]
name = "workers-research-utils-209444"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "G4brym/workers-research"
cve = ""
cwe = "CWE-89"
commit = "209444eb61cc564c2d6b43267256f85fe3e5e30e"
parent = "eab923ad3099c01b002fbd6be7cf994614bbdee4"
commit_url = "https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e"
vuln = "workers-research-utils-209444/vuln.ts"
fixed = "workers-research-utils-209444/fixed.ts"
relpath = "src/utils.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "holdout"
[[pair.expected]]
cwe = "CWE-89"
class = "sql injection"
path = "src/utils.ts"
function = "formatDuration"
mechanism = "source_reaches_sink"
evidence = "Fix SQL injection in search by using parameterized queries (#41)"
[[pair]]
name = "zoonk-origin-bfbf67"
slice = "agent-vfc"
language = "typescript"
origin = "github-agent-trailer"
license = "MIT"
repo = "zoonk/zoonk"
cve = ""
cwe = "CWE-16"
commit = "bfbf670ccb41d63c407d32c51bd26e626a174f31"
parent = "2604269350bff51f58572c133b45010cb0976a5a"
commit_url = "https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31"
vuln = "zoonk-origin-bfbf67/vuln.ts"
fixed = "zoonk-origin-bfbf67/fixed.ts"
relpath = "packages/utils/src/origin.ts"
min_recall = 1.0
fix_policy = "silent"
provenance = "agent"
split = "train"
[[pair.expected]]
cwe = "CWE-16"
class = "permissive default"
path = "packages/utils/src/origin.ts"
function = "getAllowedHosts"
mechanism = "permissive_default"
evidence = "fix(api): allow staging cors from previews (#1559)"
+4
View File
@@ -0,0 +1,4 @@
# agent-vfc pair slice. Reviewed isolated functions with provenance.
# Honesty dashboard — not the local 100% CI gate.
# Do not add these names to LANGUAGE_MANIFESTS.
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
@@ -0,0 +1,26 @@
# Provenance: jfut/dnf-plugin-anyrepo (fixed).
# repo: jfut/dnf-plugin-anyrepo
# commit: 26d19aeb8884f244e34ccfdc4f49f07055adc4d0
# parent: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
# commit_url: https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0
# cve:
# license: Apache-2.0
# function: validate_repo_name
# relpath: dnf_plugin_anyrepo/config.py
# provenance: agent
# mechanism: path_join_user_input
def validate_repo_name(name: str) -> str:
"""Validate the INI section name used as the repository alias."""
normalized = str(name).strip()
if not normalized:
raise ConfigError("repository name must not be empty")
if normalized == "main":
raise ConfigError("repository name must not be main")
# Keep the alias from resolving to the cache directory itself or its parent.
if normalized in {".", ".."}:
raise ConfigError(f"invalid repository name: {name}")
if any(char in normalized for char in "\x00\r\n[]/\\"):
raise ConfigError(f"invalid repository name: {name}")
return normalized
@@ -0,0 +1,23 @@
# Provenance: jfut/dnf-plugin-anyrepo (vuln).
# repo: jfut/dnf-plugin-anyrepo
# commit: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
# parent: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
# commit_url: https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0
# cve:
# license: Apache-2.0
# function: validate_repo_name
# relpath: dnf_plugin_anyrepo/config.py
# provenance: agent
# mechanism: path_join_user_input
def validate_repo_name(name: str) -> str:
"""Validate the INI section name used as the repository alias."""
normalized = str(name).strip()
if not normalized:
raise ConfigError("repository name must not be empty")
if normalized == "main":
raise ConfigError("repository name must not be main")
if any(char in normalized for char in "\r\n[]"):
raise ConfigError(f"invalid repository name: {name}")
return normalized
@@ -0,0 +1,442 @@
// Provenance: jardimdesoftware/edutrace (fixed).
// repo: jardimdesoftware/edutrace
// commit: ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
// parent: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
// commit_url: https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
// cve:
// license: Apache-2.0
// function: handleInputChange
// relpath: front/src/app/editar-anamnese/page.tsx
// provenance: agent
// mechanism: prototype_pollution
function AnamnesePage() {
const searchParams = useSearchParams();
const email = searchParams.get("email");
const nome = searchParams.get("nome");
const { loading } = useAuth();
const router = useRouter();
const [anamnesis, setAnamnesis] = useState<AnamnesisData | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [formData, setFormData] = useState<AnamnesisData>(initialAnamnesisState);
useEffect(() => {
async function fetchData() {
setIsLoading(true);
try {
const token = decodeToken();
if (!token) {
router.push('/login');
return;
}
const isStudent = token.id_level === ESTUDANTE;
if (token.id_level === PROFISSIONAL_EDUCACAO || isStudent) {
router.push(`/anamnese${email ? `?email=${email}&nome=${nome}` : ''}`);
return;
}
const target = isStudent ? token.email : email;
if (target) {
const data = await getAnamneseByEmail(target);
setAnamnesis(data);
setFormData(data);
}
} catch (error) {
console.error("Anamnese não encontrada, iniciando modo de criação.", error);
setAnamnesis(null);
} finally {
setIsLoading(false);
}
}
fetchData();
}, [email, nome, router]);
const handleInputChange = (name: string, value: string) => {
const keys = name.split('.');
if (keys.some((key) => key === '__proto__' || key === 'constructor' || key === 'prototype')) return;
setFormData(prevData => {
const newData = JSON.parse(JSON.stringify(prevData));
let current = newData;
for (let i = 0; i < keys.length - 1; i++) {
current = current[keys[i]];
}
current[keys[keys.length - 1]] = value;
return newData;
});
};
const handleCheckboxClick = (name: string) => {
const keys = name.split('.');
if (keys.some((key) => key === '__proto__' || key === 'constructor' || key === 'prototype')) return;
setFormData(prevData => {
// Criar uma cópia profunda para segurança
const newData = JSON.parse(JSON.stringify(prevData));
let currentSection = newData;
// Navega até o penúltimo nível do objeto
for (let i = 0; i < keys.length - 1; i++) {
currentSection = currentSection[keys[i]];
}
const finalKey = keys[keys.length - 1];
const currentValue = currentSection[finalKey];
// Inverte o valor booleano atual
currentSection[finalKey] = !currentValue;
return newData;
});
};
const handleEdit = async () => {
if (!email) {
alert("Email do estudante não encontrado para editar anamnese.");
return;
}
try {
const dadosAtualizados = { ...formData };
await patchAnamnesis(dadosAtualizados, email);
alert("Anamnese atualizada com sucesso!");
router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`);
} catch (error) {
console.error("Erro ao atualizar Anamnese: ", error);
alert("Falha ao atualizar Anamnese. Verifique o console para mais detalhes.");
}
};
if (isLoading || loading) {
return <h1>Carregando...</h1>; //ADICIONAR COMPONENTE DE LOADING
}
if (anamnesis === null) {
return (
<AppLayout
>
<div className="p-6 text-center">
<h2 className="text-xl font-bold text-green-700">O estudante ainda não possui uma Anamnese cadastrada</h2>
<button className="mt-6 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`)}>
Voltar
</button>
</div>
</AppLayout>
)
}
return (
<AppLayout
>
<div className="p-6 space-y-8 w-full">
<h1 className="text-3xl font-bold text-gray-800">Editar Anamnese</h1>
{/* Identificação */}
<section>
<h2 className="text-xl font-semibold mb-4">Identificação</h2>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nome da unidade plena" value={formData.identification.nome_unidade_plena} onInput={(e: any) => handleInputChange('identification.nome_unidade_plena', e.target.value)} />
<BrInput label="Nome completo" value={formData.identification.nome_completo} onInput={(e: any) => handleInputChange('identification.nome_completo', e.target.value)} />
<BrInput label="Data de Nascimento" value={formData.identification.data_de_nascimento} onInput={(e: any) => handleInputChange('identification.data_de_nascimento', e.target.value)} />
<BrInput label="Endereço" value={formData.identification.endereco} onInput={(e: any) => handleInputChange('identification.endereco', e.target.value)} />
<BrInput label="Bairro" value={formData.identification.bairo} onInput={(e: any) => handleInputChange('identification.bairo', e.target.value)} />
<BrInput label="CEP" value={formData.identification.cep} onInput={(e: any) => handleInputChange('identification.cep', e.target.value)} />
<BrInput label="Município" value={formData.identification.municipio} onInput={(e: any) => handleInputChange('identification.municipio', e.target.value)} />
<BrInput label="Curso" value={formData.identification.curso} onInput={(e: any) => handleInputChange('identification.curso', e.target.value)} />
<BrInput label="Série de escolaridade atual" value={formData.identification.serie_de_escolaridade_atual} onInput={(e: any) => handleInputChange('identification.serie_de_escolaridade_atual', e.target.value)} />
<BrInput label="Turma" value={formData.identification.turma} onInput={(e: any) => handleInputChange('identification.turma', e.target.value)} />
<BrInput label="Idade que iniciou os estudos" value={formData.identification.idade_iniciou_estudos} onInput={(e: any) => handleInputChange('identification.idade_iniciou_estudos', e.target.value)} />
</div>
</section>
{/* Dados Familiares */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Dados familiares</h2>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nome do pai" value={formData.family_data.nome_pai} onInput={(e: any) => handleInputChange('family_data.nome_pai', e.target.value)} />
<BrInput label="Profissão do pai" value={formData.family_data.profissao_pai} onInput={(e: any) => handleInputChange('family_data.profissao_pai', e.target.value)} />
<BrInput label="Escolaridade do pai" value={formData.family_data.escolaridade_pai} onInput={(e: any) => handleInputChange('family_data.escolaridade_pai', e.target.value)} />
<BrInput label="Idade do pai" value={formData.family_data.idade_pai} onInput={(e: any) => handleInputChange('family_data.idade_pai', e.target.value)} />
<BrInput label="Nome da mãe" value={formData.family_data.nome_mae} onInput={(e: any) => handleInputChange('family_data.nome_mae', e.target.value)} />
<BrInput label="Profissão da mãe" value={formData.family_data.profissao_mae} onInput={(e: any) => handleInputChange('family_data.profissao_mae', e.target.value)} />
<BrInput label="Escolaridade da mãe" value={formData.family_data.escolaridade_mae} onInput={(e: any) => handleInputChange('family_data.escolaridade_mae', e.target.value)} />
<BrInput label="Idade da mãe" value={formData.family_data.idade_mae} onInput={(e: any) => handleInputChange('family_data.idade_mae', e.target.value)} />
<BrInput label="Outros filhos" value={formData.family_data.outros_filhos} onInput={(e: any) => handleInputChange('family_data.outros_filhos', e.target.value)} />
</div>
<div className="mt-4 space-y-2">
<label className="text-sm font-medium text-black">União dos Pais</label>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Casados" checked={formData.family_data.uniao_pais.casados} onClick={() => handleCheckboxClick('family_data.uniao_pais.casados')} />
<BrCheckbox name="" label="Separados" checked={formData.family_data.uniao_pais.separados} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados')} />
<BrCheckbox name="" label="Separados como uma nova estrutura familiar" checked={formData.family_data.uniao_pais.separados_como_nova_estrutura_familia} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados_como_nova_estrutura_familia')} />
</div>
</div>
<div className="mt-4 space-y-2">
<label className="text-sm font-medium text-black">Pais</label>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Biológico" checked={formData.family_data.pais.biologico} onClick={() => handleCheckboxClick('family_data.pais.biologico')} />
<BrCheckbox name="" label="Adotivo" checked={formData.family_data.pais.adotivo} onClick={() => handleCheckboxClick('family_data.pais.adotivo')} />
</div>
</div>
<div className="mt-4 grid md:grid-cols-2 gap-4">
<BrInput label="Em caso de separação, o estudante vive com quem?" value={formData.family_data.estudante_reside_com_quem} onInput={(e: any) => handleInputChange('family_data.estudante_reside_com_quem', e.target.value)} />
<BrInput label="Reação do estudante à situação" value={formData.family_data.reacao_estudante_situacao} onInput={(e: any) => handleInputChange('family_data.reacao_estudante_situacao', e.target.value)} />
</div>
</section>
{/* Condições familiares do estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Condições familiares do estudante</h2>
<div className="grid md:grid-cols-3 gap-4">
<div>
<p className="text-sm font-medium mb-2">Condições de moradia</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Taipa" checked={formData.family_conditions.moradia.taipa} onClick={() => handleCheckboxClick('family_conditions.moradia.taipa')} />
<BrCheckbox name="" label="Alvenaria" checked={formData.family_conditions.moradia.alvenaria} onClick={() => handleCheckboxClick('family_conditions.moradia.alvenaria')} />
<BrCheckbox name="" label="Palafita" checked={formData.family_conditions.moradia.palafita} onClick={() => handleCheckboxClick('family_conditions.moradia.palafita')} />
</div>
</div>
<div>
<p className="text-sm font-medium mb-2">Convívio familiar</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.convivio_familiar.excelente} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.excelente')} />
<BrCheckbox name="" label="Bom" checked={formData.family_conditions.convivio_familiar.bom} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.bom')} />
<BrCheckbox name="" label="Problemático" checked={formData.family_conditions.convivio_familiar.problematico} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.problematico')} />
<BrCheckbox name="" label="Precário" checked={formData.family_conditions.convivio_familiar.precario} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.precario')} />
</div>
</div>
<div>
<p className="text-sm font-medium mb-2">Qualidade de comunicação</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.execelente} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.execelente')} />
<BrCheckbox name="" label="Boa" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.boa} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.boa')} />
<BrCheckbox name="" label="Ruim" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.ruim} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.ruim')} />
<BrCheckbox name="" label="Péssima" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.pessima} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.pessima')} />
</div>
</div>
</div>
<div className="grid md:grid-cols-2 gap-4 mt-6">
<BrInput label="Que medidas disciplinares normalmente são usadas com o estudante" value={formData.family_conditions.medidas_disciplinares_com_estudante} onInput={(e: any) => handleInputChange('family_conditions.medidas_disciplinares_com_estudante', e.target.value)} />
<BrInput label="Quem as usa" value={formData.family_conditions.quem_usa_medidas_disciplinares} onInput={(e: any) => handleInputChange('family_conditions.quem_usa_medidas_disciplinares', e.target.value)} />
<BrInput label="Quais as reações do estudante frente a essas medidas" value={formData.family_conditions.reacao_estudante_frente_medidas} onInput={(e: any) => handleInputChange('family_conditions.reacao_estudante_frente_medidas', e.target.value)} />
<BrInput label="Como reage quando contrariado" value={formData.family_conditions.reacao_contrariado} onInput={(e: any) => handleInputChange('family_conditions.reacao_contrariado', e.target.value)} />
</div>
<div className="mt-6">
<p className="text-sm font-medium mb-2">Condições do ambiente familiar para a aprendizagem escolar</p>
<BrInput label="Condição" value={formData.family_conditions.condicao_ambiente_familiar_aprendizagem_escolar} onInput={(e: any) => handleInputChange('family_conditions.condicao_ambiente_familiar_aprendizagem_escolar', e.target.value)} />
</div>
</section>
{/* Histórico da Mãe */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Histórico da Mãe</h2>
{/* Gestação */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Gestação</h3>
<div className="grid md:grid-cols-3 gap-4">
<BrInput label="Transfusão sanguínea na gravidez" value={formData.mother_background.gestacao.transfusao_sanguinea_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.transfusao_sanguinea_gravidez', e.target.value)} />
<BrInput label="Quando sentiu movimento da criança" value={formData.mother_background.gestacao.quando_sentiu_movimento_da_crianca} onInput={(e: any) => handleInputChange('mother_background.gestacao.quando_sentiu_movimento_da_crianca', e.target.value)} />
<BrInput label="Levou tombo durante a gravidez" value={formData.mother_background.gestacao.levou_tombo_durante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.levou_tombo_durante_gravidez', e.target.value)} />
<BrInput label="Doença na gestação" value={formData.mother_background.gestacao.doenca_na_gestacao} onInput={(e: any) => handleInputChange('mother_background.gestacao.doenca_na_gestacao', e.target.value)} />
<BrInput label="Condição de saúde da mãe na gravidez" value={formData.mother_background.gestacao.condicao_saude_da_mae_na_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.condicao_saude_da_mae_na_gravidez', e.target.value)} />
<BrInput label="Episódio marcante na gravidez" value={formData.mother_background.gestacao.episodio_marcante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.episodio_marcante_gravidez', e.target.value)} />
</div>
</div>
{/* Condições de Nascimento */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Condições de Nascimento</h3>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nasceu com quantos meses" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_meses} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_meses', e.target.value)} />
<BrInput label="Nasceu com quantos quilos" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_quilos} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_quilos', e.target.value)} />
<BrInput label="Nasceu com qual comprimento" value={formData.mother_background.condicoes_nascimento.nasceu_com_qual_comprimento} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_com_qual_comprimento', e.target.value)} />
<BrInput label="Desenvolvimento do parto" value={formData.mother_background.condicoes_nascimento.desenvolvimento_parto} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.desenvolvimento_parto', e.target.value)} />
</div>
</div>
{/* Primeiras Reações */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Primeiras Reações</h3>
<div className="grid md:grid-cols-3 gap-4">
<BrInput label="Chorou" value={formData.mother_background.primeiras_reacoes.chorou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.chorou', e.target.value)} />
<BrInput label="Ficou vermelho demais" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_demais} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_demais', e.target.value)} />
<BrInput label="Ficou vermelho por quanto tempo" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo', e.target.value)} />
<BrInput label="Precisou de oxigênio" value={formData.mother_background.primeiras_reacoes.precisou_de_oxigenio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.precisou_de_oxigenio', e.target.value)} />
<BrInput label="Ficou ictérico" value={formData.mother_background.primeiras_reacoes.ficou_icterico} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_icterico', e.target.value)} />
<BrInput label="Como era quando bebê" value={formData.mother_background.primeiras_reacoes.como_era_quando_bebe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.como_era_quando_bebe', e.target.value)} />
<BrInput label="Qual idade afirmou a cabeça" value={formData.mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca', e.target.value)} />
<BrInput label="Qual idade sentou sem apoio" value={formData.mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio', e.target.value)} />
<BrInput label="Qual idade engatinhou" value={formData.mother_background.primeiras_reacoes.qual_idade_engatinhou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_engatinhou', e.target.value)} />
<BrInput label="Qual idade ficou de pé" value={formData.mother_background.primeiras_reacoes.qual_idade_ficou_de_pe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_ficou_de_pe', e.target.value)} />
<BrInput label="Qual idade andou" value={formData.mother_background.primeiras_reacoes.qual_idade_andou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_andou', e.target.value)} />
</div>
</div>
</section>
{/* Linguagem Verbal (3 anos) */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Linguagem Verbal (3 anos)</h2>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<BrCheckbox name="" label="Balbuciou" checked={formData.verbal_language_three_years.balbuciou} onClick={() => handleCheckboxClick('verbal_language_three_years.balbuciou')} />
<BrCheckbox name="" label="Trocou letras" checked={formData.verbal_language_three_years.trocou_letras} onClick={() => handleCheckboxClick('verbal_language_three_years.trocou_letras')} />
<BrCheckbox name="" label="Gaguejou" checked={formData.verbal_language_three_years.gaguejou} onClick={() => handleCheckboxClick('verbal_language_three_years.gaguejou')} />
</div>
<BrInput label="Primeiras expressões" value={formData.verbal_language_three_years.primeiras_expressoes} onInput={(e: any) => handleInputChange('verbal_language_three_years.primeiras_expressoes', e.target.value)} />
</div>
</section>
{/* Desenvolvimento */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Desenvolvimento</h2>
{/* Saúde */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Saúde</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Sofreu acidente ou fez cirurgia" value={formData.development.saude.sofreu_acidente_ou_fez_cirurgia} onInput={(e: any) => handleInputChange('development.saude.sofreu_acidente_ou_fez_cirurgia', e.target.value)} />
<BrInput label="Possui alergia" value={formData.development.saude.possui_alergia} onInput={(e: any) => handleInputChange('development.saude.possui_alergia', e.target.value)} />
<BrInput label="Possui bronquite ou asma" value={formData.development.saude.possui_bronquite_ou_asma} onInput={(e: any) => handleInputChange('development.saude.possui_bronquite_ou_asma', e.target.value)} />
<BrInput label="Possui problema de visão ou audição" value={formData.development.saude.possui_problema_visao_audicao} onInput={(e: any) => handleInputChange('development.saude.possui_problema_visao_audicao', e.target.value)} />
<BrInput label="Já desmaiou" value={formData.development.saude.ja_desmaiou} onInput={(e: any) => handleInputChange('development.saude.ja_desmaiou', e.target.value)} />
<BrInput label="Quando desmaiou" value={formData.development.saude.quando_desmaiou} onInput={(e: any) => handleInputChange('development.saude.quando_desmaiou', e.target.value)} />
<BrInput label="Teve ou tem convulsões" value={formData.development.saude.teve_ou_tem_convulsoes} onInput={(e: any) => handleInputChange('development.saude.teve_ou_tem_convulsoes', e.target.value)} />
</div>
</div>
{/* Alimentação */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Alimentação</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Foi amamentada" value={formData.development.alimentacao.foi_amamentada} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amamentada', e.target.value)} />
<BrInput label="Foi amamentada até quando" value={formData.development.alimentacao.foi_amementada_ate_quando} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amementada_ate_quando', e.target.value)} />
<BrInput label="Como é sua alimentação" value={formData.development.alimentacao.como_e_sua_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.como_e_sua_alimentacao', e.target.value)} />
<BrInput label="Foi forçado a se alimentar" value={formData.development.alimentacao.foi_forcado_se_alimentar} onInput={(e: any) => handleInputChange('development.alimentacao.foi_forcado_se_alimentar', e.target.value)} />
<BrInput label="Recebe ajuda na alimentação" value={formData.development.alimentacao.recebe_ajuda_na_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.recebe_ajuda_na_alimentacao', e.target.value)} />
</div>
</div>
{/* Sono */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Sono</h3>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<BrCheckbox name="" label="Dorme bem" checked={formData.development.sono.dorme_bem} onClick={() => handleCheckboxClick('development.sono.dorme_bem')} />
<BrCheckbox name="" label="Dorme separado dos pais" checked={formData.development.sono.dorme_separado_dos_pais} onClick={() => handleCheckboxClick('development.sono.dorme_separado_dos_pais')} />
</div>
<BrInput label="Com quem dorme" value={formData.development.sono.com_quem_dorme} onInput={(e: any) => handleInputChange('development.sono.com_quem_dorme', e.target.value)} />
</div>
<div className="mt-4">
<p className="text-sm font-medium mb-2">Tipo de sono</p>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Agitado" checked={formData.development.sono.sono.agitado} onClick={() => handleCheckboxClick('development.sono.sono.agitado')} />
<BrCheckbox name="" label="Tranquilo" checked={formData.development.sono.sono.tranquilo} onClick={() => handleCheckboxClick('development.sono.sono.tranquilo')} />
<BrCheckbox name="" label="Fala dormindo" checked={formData.development.sono.sono.fala_dormindo} onClick={() => handleCheckboxClick('development.sono.sono.fala_dormindo')} />
<BrCheckbox name="" label="Sonâmbulo" checked={formData.development.sono.sono.sonambulo} onClick={() => handleCheckboxClick('development.sono.sono.sonambulo')} />
</div>
</div>
</div>
</section>
{/* Informações Escolares */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Informações Escolares</h2>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Histórico escolar comum - antecedentes relevantes" value={formData.school_information.historico_escolar_comum_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_comum_antecedentes_relevantes', e.target.value)} />
<BrInput label="Histórico escolar especial - antecedentes relevantes" value={formData.school_information.historico_escolar_especial_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_especial_antecedentes_relevantes', e.target.value)} />
<BrInput label="Deficiência apresentada pelo estudante" value={formData.school_information.deficiencia_apresentada_estudante} onInput={(e: any) => handleInputChange('school_information.deficiencia_apresentada_estudante', e.target.value)} />
<BrInput label="Foi retido alguma vez" value={formData.school_information.retido_alguma_vez} onInput={(e: any) => handleInputChange('school_information.retido_alguma_vez', e.target.value)} />
<BrInput label="Gosta de ir à escola" value={formData.school_information.gosta_de_ir_escola} onInput={(e: any) => handleInputChange('school_information.gosta_de_ir_escola', e.target.value)} />
<BrInput label="É bem aceito pelos amigos" value={formData.school_information.bem_aceito_pelos_amigous} onInput={(e: any) => handleInputChange('school_information.bem_aceito_pelos_amigous', e.target.value)} />
</div>
</section>
{/* Sexualidade */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Sexualidade</h2>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Explanação sexual" checked={formData.sexuality.explanacao_sexual} onClick={() => handleCheckboxClick('sexuality.explanacao_sexual')} />
<BrCheckbox name="" label="Curiosidade sexual" checked={formData.sexuality.curiosidade_sexual} onClick={() => handleCheckboxClick('sexuality.curiosidade_sexual')} />
<BrCheckbox name="" label="Conversa com pais sobre sexualidade" checked={formData.sexuality.conversa_com_pais_sobre_sexualidade} onClick={() => handleCheckboxClick('sexuality.conversa_com_pais_sobre_sexualidade')} />
</div>
</section>
{/* Avaliação do Estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Avaliação do Estudante</h2>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Estudante apresenta outro tipo de deficiência" value={formData.student_assessment.estudante_apresenta_outro_tipo_deficiencia} onInput={(e: any) => handleInputChange('student_assessment.estudante_apresenta_outro_tipo_deficiencia', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Apresenta DA/DF/DI/PC/TGD" checked={formData.student_assessment.apresenta_da_df_di_pc_tgd} onClick={() => handleCheckboxClick('student_assessment.apresenta_da_df_di_pc_tgd')} />
</div>
<BrInput label="Se sim, data e resultado do diagnóstico" value={formData.student_assessment.se_sim_data_e_resultado_diagnostico} onInput={(e: any) => handleInputChange('student_assessment.se_sim_data_e_resultado_diagnostico', e.target.value)} />
<BrInput label="Se não, situação quanto ao diagnóstico - tem outras dificuldades" value={formData.student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades', e.target.value)} />
<BrInput label="Se tem outras dificuldades" value={formData.student_assessment.se_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_tem_outras_dificuldades', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Usa medicamentos controlados" checked={formData.student_assessment.usa_medicamentos_controlados} onClick={() => handleCheckboxClick('student_assessment.usa_medicamentos_controlados')} />
</div>
<BrInput label="Usa quais medicamentos" value={formData.student_assessment.usa_quais_medicamentos} onInput={(e: any) => handleInputChange('student_assessment.usa_quais_medicamentos', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Medicamento interfere na aprendizagem" checked={formData.student_assessment.medicamento_interfere_aprendizagem} onClick={() => handleCheckboxClick('student_assessment.medicamento_interfere_aprendizagem')} />
</div>
<BrInput label="Se interfere na aprendizagem" value={formData.student_assessment.se_intefere_aprendizagem} onInput={(e: any) => handleInputChange('student_assessment.se_intefere_aprendizagem', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Existem recomendações da saúde" checked={formData.student_assessment.existem_recomendacoes_da_saude} onClick={() => handleCheckboxClick('student_assessment.existem_recomendacoes_da_saude')} />
</div>
<BrInput label="Se possui recomendações da saúde" value={formData.student_assessment.se_possui_recomendacoes_da_saude} onInput={(e: any) => handleInputChange('student_assessment.se_possui_recomendacoes_da_saude', e.target.value)} />
</div>
</section>
{/* Desenvolvimento do Estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Desenvolvimento do Estudante</h2>
{/* Função Cognitiva */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Cognitiva</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Percepção" value={formData.student_development.funcao_cognitiva.percepcao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.percepcao', e.target.value)} />
<BrInput label="Atenção" value={formData.student_development.funcao_cognitiva.atencao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.atencao', e.target.value)} />
<BrInput label="Memória" value={formData.student_development.funcao_cognitiva.memoria} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.memoria', e.target.value)} />
<BrInput label="Linguagem" value={formData.student_development.funcao_cognitiva.linguagem} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.linguagem', e.target.value)} />
<BrInput label="Raciocínio lógico" value={formData.student_development.funcao_cognitiva.raciocinio_logico} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.raciocinio_logico', e.target.value)} />
</div>
</div>
{/* Função Motora */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Motora</h3>
<BrInput label="Desenvolvimento e capacidade motora" value={formData.student_development.funcao_motora.desenvolvimento_e_capacidade_motora} onInput={(e: any) => handleInputChange('student_development.funcao_motora.desenvolvimento_e_capacidade_motora', e.target.value)} />
</div>
{/* Função Pessoal Social */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Pessoal Social</h3>
<BrInput label="Área emocional, afetiva e social" value={formData.student_development.funcao_pressoal_social.area_emocional_afetiva_social} onInput={(e: any) => handleInputChange('student_development.funcao_pressoal_social.area_emocional_afetiva_social', e.target.value)} />
</div>
</section>
{/* Botões */}
<div className="flex justify-center gap-4 mt-8">
<button className="bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/anamnese?email=${email}&nome=${nome}`)}>
Cancelar
</button>
<button className="bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={handleEdit}>
Salvar Alterações
</button>
</div>
</div>
</AppLayout>
);
}
@@ -0,0 +1,440 @@
// Provenance: jardimdesoftware/edutrace (vuln).
// repo: jardimdesoftware/edutrace
// commit: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
// parent: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
// commit_url: https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
// cve:
// license: Apache-2.0
// function: handleInputChange
// relpath: front/src/app/editar-anamnese/page.tsx
// provenance: agent
// mechanism: prototype_pollution
function AnamnesePage() {
const searchParams = useSearchParams();
const email = searchParams.get("email");
const nome = searchParams.get("nome");
const { loading } = useAuth();
const router = useRouter();
const [anamnesis, setAnamnesis] = useState<AnamnesisData | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [formData, setFormData] = useState<AnamnesisData>(initialAnamnesisState);
useEffect(() => {
async function fetchData() {
setIsLoading(true);
try {
const token = decodeToken();
if (!token) {
router.push('/login');
return;
}
const isStudent = token.id_level === ESTUDANTE;
if (token.id_level === PROFISSIONAL_EDUCACAO || isStudent) {
router.push(`/anamnese${email ? `?email=${email}&nome=${nome}` : ''}`);
return;
}
const target = isStudent ? token.email : email;
if (target) {
const data = await getAnamneseByEmail(target);
setAnamnesis(data);
setFormData(data);
}
} catch (error) {
console.error("Anamnese não encontrada, iniciando modo de criação.", error);
setAnamnesis(null);
} finally {
setIsLoading(false);
}
}
fetchData();
}, [email, nome, router]);
const handleInputChange = (name: string, value: string) => {
const keys = name.split('.');
setFormData(prevData => {
const newData = JSON.parse(JSON.stringify(prevData));
let current = newData;
for (let i = 0; i < keys.length - 1; i++) {
current = current[keys[i]];
}
current[keys[keys.length - 1]] = value;
return newData;
});
};
const handleCheckboxClick = (name: string) => {
const keys = name.split('.');
setFormData(prevData => {
// Criar uma cópia profunda para segurança
const newData = JSON.parse(JSON.stringify(prevData));
let currentSection = newData;
// Navega até o penúltimo nível do objeto
for (let i = 0; i < keys.length - 1; i++) {
currentSection = currentSection[keys[i]];
}
const finalKey = keys[keys.length - 1];
const currentValue = currentSection[finalKey];
// Inverte o valor booleano atual
currentSection[finalKey] = !currentValue;
return newData;
});
};
const handleEdit = async () => {
if (!email) {
alert("Email do estudante não encontrado para editar anamnese.");
return;
}
try {
const dadosAtualizados = { ...formData };
await patchAnamnesis(dadosAtualizados, email);
alert("Anamnese atualizada com sucesso!");
router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`);
} catch (error) {
console.error("Erro ao atualizar Anamnese: ", error);
alert("Falha ao atualizar Anamnese. Verifique o console para mais detalhes.");
}
};
if (isLoading || loading) {
return <h1>Carregando...</h1>; //ADICIONAR COMPONENTE DE LOADING
}
if (anamnesis === null) {
return (
<AppLayout
>
<div className="p-6 text-center">
<h2 className="text-xl font-bold text-green-700">O estudante ainda não possui uma Anamnese cadastrada</h2>
<button className="mt-6 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`)}>
Voltar
</button>
</div>
</AppLayout>
)
}
return (
<AppLayout
>
<div className="p-6 space-y-8 w-full">
<h1 className="text-3xl font-bold text-gray-800">Editar Anamnese</h1>
{/* Identificação */}
<section>
<h2 className="text-xl font-semibold mb-4">Identificação</h2>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nome da unidade plena" value={formData.identification.nome_unidade_plena} onInput={(e: any) => handleInputChange('identification.nome_unidade_plena', e.target.value)} />
<BrInput label="Nome completo" value={formData.identification.nome_completo} onInput={(e: any) => handleInputChange('identification.nome_completo', e.target.value)} />
<BrInput label="Data de Nascimento" value={formData.identification.data_de_nascimento} onInput={(e: any) => handleInputChange('identification.data_de_nascimento', e.target.value)} />
<BrInput label="Endereço" value={formData.identification.endereco} onInput={(e: any) => handleInputChange('identification.endereco', e.target.value)} />
<BrInput label="Bairro" value={formData.identification.bairo} onInput={(e: any) => handleInputChange('identification.bairo', e.target.value)} />
<BrInput label="CEP" value={formData.identification.cep} onInput={(e: any) => handleInputChange('identification.cep', e.target.value)} />
<BrInput label="Município" value={formData.identification.municipio} onInput={(e: any) => handleInputChange('identification.municipio', e.target.value)} />
<BrInput label="Curso" value={formData.identification.curso} onInput={(e: any) => handleInputChange('identification.curso', e.target.value)} />
<BrInput label="Série de escolaridade atual" value={formData.identification.serie_de_escolaridade_atual} onInput={(e: any) => handleInputChange('identification.serie_de_escolaridade_atual', e.target.value)} />
<BrInput label="Turma" value={formData.identification.turma} onInput={(e: any) => handleInputChange('identification.turma', e.target.value)} />
<BrInput label="Idade que iniciou os estudos" value={formData.identification.idade_iniciou_estudos} onInput={(e: any) => handleInputChange('identification.idade_iniciou_estudos', e.target.value)} />
</div>
</section>
{/* Dados Familiares */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Dados familiares</h2>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nome do pai" value={formData.family_data.nome_pai} onInput={(e: any) => handleInputChange('family_data.nome_pai', e.target.value)} />
<BrInput label="Profissão do pai" value={formData.family_data.profissao_pai} onInput={(e: any) => handleInputChange('family_data.profissao_pai', e.target.value)} />
<BrInput label="Escolaridade do pai" value={formData.family_data.escolaridade_pai} onInput={(e: any) => handleInputChange('family_data.escolaridade_pai', e.target.value)} />
<BrInput label="Idade do pai" value={formData.family_data.idade_pai} onInput={(e: any) => handleInputChange('family_data.idade_pai', e.target.value)} />
<BrInput label="Nome da mãe" value={formData.family_data.nome_mae} onInput={(e: any) => handleInputChange('family_data.nome_mae', e.target.value)} />
<BrInput label="Profissão da mãe" value={formData.family_data.profissao_mae} onInput={(e: any) => handleInputChange('family_data.profissao_mae', e.target.value)} />
<BrInput label="Escolaridade da mãe" value={formData.family_data.escolaridade_mae} onInput={(e: any) => handleInputChange('family_data.escolaridade_mae', e.target.value)} />
<BrInput label="Idade da mãe" value={formData.family_data.idade_mae} onInput={(e: any) => handleInputChange('family_data.idade_mae', e.target.value)} />
<BrInput label="Outros filhos" value={formData.family_data.outros_filhos} onInput={(e: any) => handleInputChange('family_data.outros_filhos', e.target.value)} />
</div>
<div className="mt-4 space-y-2">
<label className="text-sm font-medium text-black">União dos Pais</label>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Casados" checked={formData.family_data.uniao_pais.casados} onClick={() => handleCheckboxClick('family_data.uniao_pais.casados')} />
<BrCheckbox name="" label="Separados" checked={formData.family_data.uniao_pais.separados} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados')} />
<BrCheckbox name="" label="Separados como uma nova estrutura familiar" checked={formData.family_data.uniao_pais.separados_como_nova_estrutura_familia} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados_como_nova_estrutura_familia')} />
</div>
</div>
<div className="mt-4 space-y-2">
<label className="text-sm font-medium text-black">Pais</label>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Biológico" checked={formData.family_data.pais.biologico} onClick={() => handleCheckboxClick('family_data.pais.biologico')} />
<BrCheckbox name="" label="Adotivo" checked={formData.family_data.pais.adotivo} onClick={() => handleCheckboxClick('family_data.pais.adotivo')} />
</div>
</div>
<div className="mt-4 grid md:grid-cols-2 gap-4">
<BrInput label="Em caso de separação, o estudante vive com quem?" value={formData.family_data.estudante_reside_com_quem} onInput={(e: any) => handleInputChange('family_data.estudante_reside_com_quem', e.target.value)} />
<BrInput label="Reação do estudante à situação" value={formData.family_data.reacao_estudante_situacao} onInput={(e: any) => handleInputChange('family_data.reacao_estudante_situacao', e.target.value)} />
</div>
</section>
{/* Condições familiares do estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Condições familiares do estudante</h2>
<div className="grid md:grid-cols-3 gap-4">
<div>
<p className="text-sm font-medium mb-2">Condições de moradia</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Taipa" checked={formData.family_conditions.moradia.taipa} onClick={() => handleCheckboxClick('family_conditions.moradia.taipa')} />
<BrCheckbox name="" label="Alvenaria" checked={formData.family_conditions.moradia.alvenaria} onClick={() => handleCheckboxClick('family_conditions.moradia.alvenaria')} />
<BrCheckbox name="" label="Palafita" checked={formData.family_conditions.moradia.palafita} onClick={() => handleCheckboxClick('family_conditions.moradia.palafita')} />
</div>
</div>
<div>
<p className="text-sm font-medium mb-2">Convívio familiar</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.convivio_familiar.excelente} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.excelente')} />
<BrCheckbox name="" label="Bom" checked={formData.family_conditions.convivio_familiar.bom} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.bom')} />
<BrCheckbox name="" label="Problemático" checked={formData.family_conditions.convivio_familiar.problematico} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.problematico')} />
<BrCheckbox name="" label="Precário" checked={formData.family_conditions.convivio_familiar.precario} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.precario')} />
</div>
</div>
<div>
<p className="text-sm font-medium mb-2">Qualidade de comunicação</p>
<div className="flex space-x-3">
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.execelente} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.execelente')} />
<BrCheckbox name="" label="Boa" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.boa} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.boa')} />
<BrCheckbox name="" label="Ruim" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.ruim} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.ruim')} />
<BrCheckbox name="" label="Péssima" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.pessima} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.pessima')} />
</div>
</div>
</div>
<div className="grid md:grid-cols-2 gap-4 mt-6">
<BrInput label="Que medidas disciplinares normalmente são usadas com o estudante" value={formData.family_conditions.medidas_disciplinares_com_estudante} onInput={(e: any) => handleInputChange('family_conditions.medidas_disciplinares_com_estudante', e.target.value)} />
<BrInput label="Quem as usa" value={formData.family_conditions.quem_usa_medidas_disciplinares} onInput={(e: any) => handleInputChange('family_conditions.quem_usa_medidas_disciplinares', e.target.value)} />
<BrInput label="Quais as reações do estudante frente a essas medidas" value={formData.family_conditions.reacao_estudante_frente_medidas} onInput={(e: any) => handleInputChange('family_conditions.reacao_estudante_frente_medidas', e.target.value)} />
<BrInput label="Como reage quando contrariado" value={formData.family_conditions.reacao_contrariado} onInput={(e: any) => handleInputChange('family_conditions.reacao_contrariado', e.target.value)} />
</div>
<div className="mt-6">
<p className="text-sm font-medium mb-2">Condições do ambiente familiar para a aprendizagem escolar</p>
<BrInput label="Condição" value={formData.family_conditions.condicao_ambiente_familiar_aprendizagem_escolar} onInput={(e: any) => handleInputChange('family_conditions.condicao_ambiente_familiar_aprendizagem_escolar', e.target.value)} />
</div>
</section>
{/* Histórico da Mãe */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Histórico da Mãe</h2>
{/* Gestação */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Gestação</h3>
<div className="grid md:grid-cols-3 gap-4">
<BrInput label="Transfusão sanguínea na gravidez" value={formData.mother_background.gestacao.transfusao_sanguinea_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.transfusao_sanguinea_gravidez', e.target.value)} />
<BrInput label="Quando sentiu movimento da criança" value={formData.mother_background.gestacao.quando_sentiu_movimento_da_crianca} onInput={(e: any) => handleInputChange('mother_background.gestacao.quando_sentiu_movimento_da_crianca', e.target.value)} />
<BrInput label="Levou tombo durante a gravidez" value={formData.mother_background.gestacao.levou_tombo_durante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.levou_tombo_durante_gravidez', e.target.value)} />
<BrInput label="Doença na gestação" value={formData.mother_background.gestacao.doenca_na_gestacao} onInput={(e: any) => handleInputChange('mother_background.gestacao.doenca_na_gestacao', e.target.value)} />
<BrInput label="Condição de saúde da mãe na gravidez" value={formData.mother_background.gestacao.condicao_saude_da_mae_na_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.condicao_saude_da_mae_na_gravidez', e.target.value)} />
<BrInput label="Episódio marcante na gravidez" value={formData.mother_background.gestacao.episodio_marcante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.episodio_marcante_gravidez', e.target.value)} />
</div>
</div>
{/* Condições de Nascimento */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Condições de Nascimento</h3>
<div className="grid md:grid-cols-4 gap-4">
<BrInput label="Nasceu com quantos meses" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_meses} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_meses', e.target.value)} />
<BrInput label="Nasceu com quantos quilos" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_quilos} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_quilos', e.target.value)} />
<BrInput label="Nasceu com qual comprimento" value={formData.mother_background.condicoes_nascimento.nasceu_com_qual_comprimento} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_com_qual_comprimento', e.target.value)} />
<BrInput label="Desenvolvimento do parto" value={formData.mother_background.condicoes_nascimento.desenvolvimento_parto} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.desenvolvimento_parto', e.target.value)} />
</div>
</div>
{/* Primeiras Reações */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Primeiras Reações</h3>
<div className="grid md:grid-cols-3 gap-4">
<BrInput label="Chorou" value={formData.mother_background.primeiras_reacoes.chorou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.chorou', e.target.value)} />
<BrInput label="Ficou vermelho demais" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_demais} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_demais', e.target.value)} />
<BrInput label="Ficou vermelho por quanto tempo" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo', e.target.value)} />
<BrInput label="Precisou de oxigênio" value={formData.mother_background.primeiras_reacoes.precisou_de_oxigenio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.precisou_de_oxigenio', e.target.value)} />
<BrInput label="Ficou ictérico" value={formData.mother_background.primeiras_reacoes.ficou_icterico} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_icterico', e.target.value)} />
<BrInput label="Como era quando bebê" value={formData.mother_background.primeiras_reacoes.como_era_quando_bebe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.como_era_quando_bebe', e.target.value)} />
<BrInput label="Qual idade afirmou a cabeça" value={formData.mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca', e.target.value)} />
<BrInput label="Qual idade sentou sem apoio" value={formData.mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio', e.target.value)} />
<BrInput label="Qual idade engatinhou" value={formData.mother_background.primeiras_reacoes.qual_idade_engatinhou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_engatinhou', e.target.value)} />
<BrInput label="Qual idade ficou de pé" value={formData.mother_background.primeiras_reacoes.qual_idade_ficou_de_pe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_ficou_de_pe', e.target.value)} />
<BrInput label="Qual idade andou" value={formData.mother_background.primeiras_reacoes.qual_idade_andou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_andou', e.target.value)} />
</div>
</div>
</section>
{/* Linguagem Verbal (3 anos) */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Linguagem Verbal (3 anos)</h2>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<BrCheckbox name="" label="Balbuciou" checked={formData.verbal_language_three_years.balbuciou} onClick={() => handleCheckboxClick('verbal_language_three_years.balbuciou')} />
<BrCheckbox name="" label="Trocou letras" checked={formData.verbal_language_three_years.trocou_letras} onClick={() => handleCheckboxClick('verbal_language_three_years.trocou_letras')} />
<BrCheckbox name="" label="Gaguejou" checked={formData.verbal_language_three_years.gaguejou} onClick={() => handleCheckboxClick('verbal_language_three_years.gaguejou')} />
</div>
<BrInput label="Primeiras expressões" value={formData.verbal_language_three_years.primeiras_expressoes} onInput={(e: any) => handleInputChange('verbal_language_three_years.primeiras_expressoes', e.target.value)} />
</div>
</section>
{/* Desenvolvimento */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Desenvolvimento</h2>
{/* Saúde */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Saúde</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Sofreu acidente ou fez cirurgia" value={formData.development.saude.sofreu_acidente_ou_fez_cirurgia} onInput={(e: any) => handleInputChange('development.saude.sofreu_acidente_ou_fez_cirurgia', e.target.value)} />
<BrInput label="Possui alergia" value={formData.development.saude.possui_alergia} onInput={(e: any) => handleInputChange('development.saude.possui_alergia', e.target.value)} />
<BrInput label="Possui bronquite ou asma" value={formData.development.saude.possui_bronquite_ou_asma} onInput={(e: any) => handleInputChange('development.saude.possui_bronquite_ou_asma', e.target.value)} />
<BrInput label="Possui problema de visão ou audição" value={formData.development.saude.possui_problema_visao_audicao} onInput={(e: any) => handleInputChange('development.saude.possui_problema_visao_audicao', e.target.value)} />
<BrInput label="Já desmaiou" value={formData.development.saude.ja_desmaiou} onInput={(e: any) => handleInputChange('development.saude.ja_desmaiou', e.target.value)} />
<BrInput label="Quando desmaiou" value={formData.development.saude.quando_desmaiou} onInput={(e: any) => handleInputChange('development.saude.quando_desmaiou', e.target.value)} />
<BrInput label="Teve ou tem convulsões" value={formData.development.saude.teve_ou_tem_convulsoes} onInput={(e: any) => handleInputChange('development.saude.teve_ou_tem_convulsoes', e.target.value)} />
</div>
</div>
{/* Alimentação */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Alimentação</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Foi amamentada" value={formData.development.alimentacao.foi_amamentada} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amamentada', e.target.value)} />
<BrInput label="Foi amamentada até quando" value={formData.development.alimentacao.foi_amementada_ate_quando} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amementada_ate_quando', e.target.value)} />
<BrInput label="Como é sua alimentação" value={formData.development.alimentacao.como_e_sua_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.como_e_sua_alimentacao', e.target.value)} />
<BrInput label="Foi forçado a se alimentar" value={formData.development.alimentacao.foi_forcado_se_alimentar} onInput={(e: any) => handleInputChange('development.alimentacao.foi_forcado_se_alimentar', e.target.value)} />
<BrInput label="Recebe ajuda na alimentação" value={formData.development.alimentacao.recebe_ajuda_na_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.recebe_ajuda_na_alimentacao', e.target.value)} />
</div>
</div>
{/* Sono */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Sono</h3>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<BrCheckbox name="" label="Dorme bem" checked={formData.development.sono.dorme_bem} onClick={() => handleCheckboxClick('development.sono.dorme_bem')} />
<BrCheckbox name="" label="Dorme separado dos pais" checked={formData.development.sono.dorme_separado_dos_pais} onClick={() => handleCheckboxClick('development.sono.dorme_separado_dos_pais')} />
</div>
<BrInput label="Com quem dorme" value={formData.development.sono.com_quem_dorme} onInput={(e: any) => handleInputChange('development.sono.com_quem_dorme', e.target.value)} />
</div>
<div className="mt-4">
<p className="text-sm font-medium mb-2">Tipo de sono</p>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Agitado" checked={formData.development.sono.sono.agitado} onClick={() => handleCheckboxClick('development.sono.sono.agitado')} />
<BrCheckbox name="" label="Tranquilo" checked={formData.development.sono.sono.tranquilo} onClick={() => handleCheckboxClick('development.sono.sono.tranquilo')} />
<BrCheckbox name="" label="Fala dormindo" checked={formData.development.sono.sono.fala_dormindo} onClick={() => handleCheckboxClick('development.sono.sono.fala_dormindo')} />
<BrCheckbox name="" label="Sonâmbulo" checked={formData.development.sono.sono.sonambulo} onClick={() => handleCheckboxClick('development.sono.sono.sonambulo')} />
</div>
</div>
</div>
</section>
{/* Informações Escolares */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Informações Escolares</h2>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Histórico escolar comum - antecedentes relevantes" value={formData.school_information.historico_escolar_comum_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_comum_antecedentes_relevantes', e.target.value)} />
<BrInput label="Histórico escolar especial - antecedentes relevantes" value={formData.school_information.historico_escolar_especial_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_especial_antecedentes_relevantes', e.target.value)} />
<BrInput label="Deficiência apresentada pelo estudante" value={formData.school_information.deficiencia_apresentada_estudante} onInput={(e: any) => handleInputChange('school_information.deficiencia_apresentada_estudante', e.target.value)} />
<BrInput label="Foi retido alguma vez" value={formData.school_information.retido_alguma_vez} onInput={(e: any) => handleInputChange('school_information.retido_alguma_vez', e.target.value)} />
<BrInput label="Gosta de ir à escola" value={formData.school_information.gosta_de_ir_escola} onInput={(e: any) => handleInputChange('school_information.gosta_de_ir_escola', e.target.value)} />
<BrInput label="É bem aceito pelos amigos" value={formData.school_information.bem_aceito_pelos_amigous} onInput={(e: any) => handleInputChange('school_information.bem_aceito_pelos_amigous', e.target.value)} />
</div>
</section>
{/* Sexualidade */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Sexualidade</h2>
<div className="flex flex-wrap gap-4">
<BrCheckbox name="" label="Explanação sexual" checked={formData.sexuality.explanacao_sexual} onClick={() => handleCheckboxClick('sexuality.explanacao_sexual')} />
<BrCheckbox name="" label="Curiosidade sexual" checked={formData.sexuality.curiosidade_sexual} onClick={() => handleCheckboxClick('sexuality.curiosidade_sexual')} />
<BrCheckbox name="" label="Conversa com pais sobre sexualidade" checked={formData.sexuality.conversa_com_pais_sobre_sexualidade} onClick={() => handleCheckboxClick('sexuality.conversa_com_pais_sobre_sexualidade')} />
</div>
</section>
{/* Avaliação do Estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Avaliação do Estudante</h2>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Estudante apresenta outro tipo de deficiência" value={formData.student_assessment.estudante_apresenta_outro_tipo_deficiencia} onInput={(e: any) => handleInputChange('student_assessment.estudante_apresenta_outro_tipo_deficiencia', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Apresenta DA/DF/DI/PC/TGD" checked={formData.student_assessment.apresenta_da_df_di_pc_tgd} onClick={() => handleCheckboxClick('student_assessment.apresenta_da_df_di_pc_tgd')} />
</div>
<BrInput label="Se sim, data e resultado do diagnóstico" value={formData.student_assessment.se_sim_data_e_resultado_diagnostico} onInput={(e: any) => handleInputChange('student_assessment.se_sim_data_e_resultado_diagnostico', e.target.value)} />
<BrInput label="Se não, situação quanto ao diagnóstico - tem outras dificuldades" value={formData.student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades', e.target.value)} />
<BrInput label="Se tem outras dificuldades" value={formData.student_assessment.se_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_tem_outras_dificuldades', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Usa medicamentos controlados" checked={formData.student_assessment.usa_medicamentos_controlados} onClick={() => handleCheckboxClick('student_assessment.usa_medicamentos_controlados')} />
</div>
<BrInput label="Usa quais medicamentos" value={formData.student_assessment.usa_quais_medicamentos} onInput={(e: any) => handleInputChange('student_assessment.usa_quais_medicamentos', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Medicamento interfere na aprendizagem" checked={formData.student_assessment.medicamento_interfere_aprendizagem} onClick={() => handleCheckboxClick('student_assessment.medicamento_interfere_aprendizagem')} />
</div>
<BrInput label="Se interfere na aprendizagem" value={formData.student_assessment.se_intefere_aprendizagem} onInput={(e: any) => handleInputChange('student_assessment.se_intefere_aprendizagem', e.target.value)} />
<div className="space-y-2">
<BrCheckbox name="" label="Existem recomendações da saúde" checked={formData.student_assessment.existem_recomendacoes_da_saude} onClick={() => handleCheckboxClick('student_assessment.existem_recomendacoes_da_saude')} />
</div>
<BrInput label="Se possui recomendações da saúde" value={formData.student_assessment.se_possui_recomendacoes_da_saude} onInput={(e: any) => handleInputChange('student_assessment.se_possui_recomendacoes_da_saude', e.target.value)} />
</div>
</section>
{/* Desenvolvimento do Estudante */}
<section className="border-t pt-6 mt-6">
<h2 className="text-xl font-semibold mb-4">Desenvolvimento do Estudante</h2>
{/* Função Cognitiva */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Cognitiva</h3>
<div className="grid md:grid-cols-2 gap-4">
<BrInput label="Percepção" value={formData.student_development.funcao_cognitiva.percepcao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.percepcao', e.target.value)} />
<BrInput label="Atenção" value={formData.student_development.funcao_cognitiva.atencao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.atencao', e.target.value)} />
<BrInput label="Memória" value={formData.student_development.funcao_cognitiva.memoria} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.memoria', e.target.value)} />
<BrInput label="Linguagem" value={formData.student_development.funcao_cognitiva.linguagem} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.linguagem', e.target.value)} />
<BrInput label="Raciocínio lógico" value={formData.student_development.funcao_cognitiva.raciocinio_logico} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.raciocinio_logico', e.target.value)} />
</div>
</div>
{/* Função Motora */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Motora</h3>
<BrInput label="Desenvolvimento e capacidade motora" value={formData.student_development.funcao_motora.desenvolvimento_e_capacidade_motora} onInput={(e: any) => handleInputChange('student_development.funcao_motora.desenvolvimento_e_capacidade_motora', e.target.value)} />
</div>
{/* Função Pessoal Social */}
<div className="mb-6">
<h3 className="text-lg font-medium mb-3">Função Pessoal Social</h3>
<BrInput label="Área emocional, afetiva e social" value={formData.student_development.funcao_pressoal_social.area_emocional_afetiva_social} onInput={(e: any) => handleInputChange('student_development.funcao_pressoal_social.area_emocional_afetiva_social', e.target.value)} />
</div>
</section>
{/* Botões */}
<div className="flex justify-center gap-4 mt-8">
<button className="bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/anamnese?email=${email}&nome=${nome}`)}>
Cancelar
</button>
<button className="bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={handleEdit}>
Salvar Alterações
</button>
</div>
</div>
</AppLayout>
);
}
@@ -0,0 +1,30 @@
// Provenance: dayflower/etude-lexical-markdown (fixed).
// repo: dayflower/etude-lexical-markdown
// commit: c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
// parent: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
if (FORBIDDEN_KEYS.has(key)) continue;
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
@@ -0,0 +1,29 @@
// Provenance: dayflower/etude-lexical-markdown (vuln).
// repo: dayflower/etude-lexical-markdown
// commit: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
// parent: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
@@ -0,0 +1,30 @@
// Provenance: dayflower/etude-lexical-markdown (fixed).
// repo: dayflower/etude-lexical-markdown
// commit: db4f54b1ab80ad596de6425e84f90aa781c49999
// parent: 1c865815d05b072f4973388c3ac66b6696d9efde
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
if (isForbiddenKey(key)) continue;
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
@@ -0,0 +1,30 @@
// Provenance: dayflower/etude-lexical-markdown (vuln).
// repo: dayflower/etude-lexical-markdown
// commit: 1c865815d05b072f4973388c3ac66b6696d9efde
// parent: 1c865815d05b072f4973388c3ac66b6696d9efde
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
if (FORBIDDEN_KEYS.has(key)) continue;
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,31 @@
// Provenance: navaneethbv/market-cap (fixed).
// repo: navaneethbv/market-cap
// commit: 4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
// parent: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
// commit_url: https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
// cve:
// license: MIT
// function: GET
// relpath: app/auth/confirm/route.ts
// provenance: agent
// mechanism: source_reaches_sink
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const token_hash = searchParams.get("token_hash");
const type = searchParams.get("type") as EmailOtpType | null;
const nextParam = searchParams.get("next") ?? "/";
// Only allow same-origin relative paths to prevent open redirects
const next =
nextParam.startsWith("/") && !nextParam.startsWith("//") ? nextParam : "/";
if (token_hash && type) {
const supabase = await createClient();
const { error } = await supabase.auth.verifyOtp({ type, token_hash });
if (!error) {
return NextResponse.redirect(new URL(next, request.url));
}
}
return NextResponse.redirect(new URL("/login?error=confirm", request.url));
}
@@ -0,0 +1,28 @@
// Provenance: navaneethbv/market-cap (vuln).
// repo: navaneethbv/market-cap
// commit: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
// parent: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
// commit_url: https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
// cve:
// license: MIT
// function: GET
// relpath: app/auth/confirm/route.ts
// provenance: agent
// mechanism: source_reaches_sink
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const token_hash = searchParams.get("token_hash");
const type = searchParams.get("type") as EmailOtpType | null;
const next = searchParams.get("next") ?? "/";
if (token_hash && type) {
const supabase = await createClient();
const { error } = await supabase.auth.verifyOtp({ type, token_hash });
if (!error) {
return NextResponse.redirect(new URL(next, request.url));
}
}
return NextResponse.redirect(new URL("/login?error=confirm", request.url));
}
@@ -0,0 +1,126 @@
// Provenance: alexshao3/melodix (fixed).
// repo: alexshao3/melodix
// commit: 089931ef71ea1e5b7586520baf1a5498e2f05b13
// parent: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
// commit_url: https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13
// cve:
// license: MIT
// function: PlayerProvider
// relpath: apps/miniapp/src/components/PlayerProvider.tsx
// provenance: agent
// mechanism: permissive_default
export function PlayerProvider({ children }: { children: React.ReactNode }) {
const audioRef = useRef<HTMLAudioElement | null>(null);
const [currentTrack, setCurrentTrack] = useState<Track | null>(null);
const [queue, setQueue] = useState<Track[]>([]);
const [history, setHistory] = useState<Track[]>([]);
const [isPlaying, setIsPlaying] = useState(false);
const [position, setPosition] = useState(0);
const [duration, setDuration] = useState(0);
const handleEndedRef = useRef<() => void>(() => {});
useEffect(() => {
const a = new Audio();
a.preload = 'metadata';
audioRef.current = a;
const t = () => setPosition(a.currentTime);
const l = () => setDuration(a.duration || 0);
const p = () => setIsPlaying(true);
const ps = () => setIsPlaying(false);
const e = () => handleEndedRef.current?.();
a.addEventListener('timeupdate', t);
a.addEventListener('loadedmetadata', l);
a.addEventListener('play', p);
a.addEventListener('pause', ps);
a.addEventListener('ended', e);
return () => {
a.pause();
a.removeEventListener('timeupdate', t);
a.removeEventListener('loadedmetadata', l);
a.removeEventListener('play', p);
a.removeEventListener('pause', ps);
a.removeEventListener('ended', e);
};
}, []);
const playTrack = useCallback((t: Track) => {
const a = audioRef.current;
if (!a) return;
a.src = t.streamUrl ?? t.audioUrl;
setCurrentTrack(t);
setPosition(0);
pushRecentlyPlayed(t);
// Best-effort server-side history mirror; `recordPlay` no-ops for guests.
void api.recordPlay(t.id);
a.play().catch(() => undefined);
}, []);
const play = useCallback(
(track: Track, newQueue?: Track[]) => {
tgHaptic('light');
if (newQueue) {
const idx = newQueue.findIndex((t) => t.id === track.id);
const upcoming =
idx >= 0 ? newQueue.slice(idx + 1) : newQueue.filter((t) => t.id !== track.id);
setQueue(upcoming);
}
if (currentTrack && currentTrack.id !== track.id) {
setHistory((h) => [...h.slice(-19), currentTrack]);
}
playTrack(track);
},
[currentTrack, playTrack],
);
const toggle = useCallback(() => {
const a = audioRef.current;
if (!a || !currentTrack) return;
tgHaptic('light');
if (a.paused) a.play();
else a.pause();
}, [currentTrack]);
const next = useCallback(() => {
if (queue.length === 0) return;
const [head, ...rest] = queue;
if (!head) return;
if (currentTrack) setHistory((h) => [...h.slice(-19), currentTrack]);
setQueue(rest);
playTrack(head);
}, [queue, currentTrack, playTrack]);
const prev = useCallback(() => {
const a = audioRef.current;
if (a && a.currentTime > 3) {
a.currentTime = 0;
return;
}
const last = history[history.length - 1];
if (!last) {
if (a) a.currentTime = 0;
return;
}
setHistory((h) => h.slice(0, -1));
if (currentTrack) setQueue((q) => [currentTrack, ...q]);
playTrack(last);
}, [history, currentTrack, playTrack]);
useEffect(() => {
handleEndedRef.current = () => next();
}, [next]);
const seek = useCallback((s: number) => {
const a = audioRef.current;
if (!a) return;
a.currentTime = s;
setPosition(s);
}, []);
const value = useMemo(
() => ({ currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek }),
[currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek],
);
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
}
@@ -0,0 +1,127 @@
// Provenance: alexshao3/melodix (vuln).
// repo: alexshao3/melodix
// commit: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
// parent: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
// commit_url: https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13
// cve:
// license: MIT
// function: PlayerProvider
// relpath: apps/miniapp/src/components/PlayerProvider.tsx
// provenance: agent
// mechanism: permissive_default
export function PlayerProvider({ children }: { children: React.ReactNode }) {
const audioRef = useRef<HTMLAudioElement | null>(null);
const [currentTrack, setCurrentTrack] = useState<Track | null>(null);
const [queue, setQueue] = useState<Track[]>([]);
const [history, setHistory] = useState<Track[]>([]);
const [isPlaying, setIsPlaying] = useState(false);
const [position, setPosition] = useState(0);
const [duration, setDuration] = useState(0);
const handleEndedRef = useRef<() => void>(() => {});
useEffect(() => {
const a = new Audio();
a.crossOrigin = 'anonymous';
a.preload = 'metadata';
audioRef.current = a;
const t = () => setPosition(a.currentTime);
const l = () => setDuration(a.duration || 0);
const p = () => setIsPlaying(true);
const ps = () => setIsPlaying(false);
const e = () => handleEndedRef.current?.();
a.addEventListener('timeupdate', t);
a.addEventListener('loadedmetadata', l);
a.addEventListener('play', p);
a.addEventListener('pause', ps);
a.addEventListener('ended', e);
return () => {
a.pause();
a.removeEventListener('timeupdate', t);
a.removeEventListener('loadedmetadata', l);
a.removeEventListener('play', p);
a.removeEventListener('pause', ps);
a.removeEventListener('ended', e);
};
}, []);
const playTrack = useCallback((t: Track) => {
const a = audioRef.current;
if (!a) return;
a.src = t.streamUrl ?? t.audioUrl;
setCurrentTrack(t);
setPosition(0);
pushRecentlyPlayed(t);
// Best-effort server-side history mirror; `recordPlay` no-ops for guests.
void api.recordPlay(t.id);
a.play().catch(() => undefined);
}, []);
const play = useCallback(
(track: Track, newQueue?: Track[]) => {
tgHaptic('light');
if (newQueue) {
const idx = newQueue.findIndex((t) => t.id === track.id);
const upcoming =
idx >= 0 ? newQueue.slice(idx + 1) : newQueue.filter((t) => t.id !== track.id);
setQueue(upcoming);
}
if (currentTrack && currentTrack.id !== track.id) {
setHistory((h) => [...h.slice(-19), currentTrack]);
}
playTrack(track);
},
[currentTrack, playTrack],
);
const toggle = useCallback(() => {
const a = audioRef.current;
if (!a || !currentTrack) return;
tgHaptic('light');
if (a.paused) a.play();
else a.pause();
}, [currentTrack]);
const next = useCallback(() => {
if (queue.length === 0) return;
const [head, ...rest] = queue;
if (!head) return;
if (currentTrack) setHistory((h) => [...h.slice(-19), currentTrack]);
setQueue(rest);
playTrack(head);
}, [queue, currentTrack, playTrack]);
const prev = useCallback(() => {
const a = audioRef.current;
if (a && a.currentTime > 3) {
a.currentTime = 0;
return;
}
const last = history[history.length - 1];
if (!last) {
if (a) a.currentTime = 0;
return;
}
setHistory((h) => h.slice(0, -1));
if (currentTrack) setQueue((q) => [currentTrack, ...q]);
playTrack(last);
}, [history, currentTrack, playTrack]);
useEffect(() => {
handleEndedRef.current = () => next();
}, [next]);
const seek = useCallback((s: number) => {
const a = audioRef.current;
if (!a) return;
a.currentTime = s;
setPosition(s);
}, []);
const value = useMemo(
() => ({ currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek }),
[currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek],
);
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
}
@@ -0,0 +1,46 @@
// Provenance: handielson/Mercado-do-vale-news (fixed).
// repo: handielson/Mercado-do-vale-news
// commit: 9b5fcf2dae41e56f5f97952266f2d6ba59598598
// parent: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
// commit_url: https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598
// cve:
// license: MIT
// function: fetchMetadata
// relpath: services/catalogMetadataService.ts
// provenance: agent
// mechanism: permissive_default
async function fetchMetadata(): Promise<MetadataCache | null> {
// Deduplicação de requisições concorrentes
if (pendingFetch) return pendingFetch;
pendingFetch = (async () => {
try {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10000);
// Bypass completo de cache de CDN e Browser
const timestamp = Date.now();
const res = await fetch(buildVpsUrl(`/catalog/metadata?_t=${timestamp}`), {
signal: controller.signal,
headers: { Accept: 'application/json' },
cache: 'no-store',
});
clearTimeout(timer);
if (!res.ok) return null;
const data = await res.json();
return {
categories: data.categories || [],
brands: data.brands || [],
priceRange: data.priceRange || null,
timestamp: Date.now(),
};
} catch {
return null;
} finally {
pendingFetch = null;
}
})();
return pendingFetch;
}
@@ -0,0 +1,50 @@
// Provenance: handielson/Mercado-do-vale-news (vuln).
// repo: handielson/Mercado-do-vale-news
// commit: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
// parent: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
// commit_url: https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598
// cve:
// license: MIT
// function: fetchMetadata
// relpath: services/catalogMetadataService.ts
// provenance: agent
// mechanism: permissive_default
async function fetchMetadata(): Promise<MetadataCache | null> {
// Deduplicação de requisições concorrentes
if (pendingFetch) return pendingFetch;
pendingFetch = (async () => {
try {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10000);
// Bypass completo de cache de CDN e Browser
const timestamp = Date.now();
const res = await fetch(buildVpsUrl(`/catalog/metadata?_t=${timestamp}`), {
signal: controller.signal,
headers: {
Accept: 'application/json',
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache'
},
cache: 'no-store',
});
clearTimeout(timer);
if (!res.ok) return null;
const data = await res.json();
return {
categories: data.categories || [],
brands: data.brands || [],
priceRange: data.priceRange || null,
timestamp: Date.now(),
};
} catch {
return null;
} finally {
pendingFetch = null;
}
})();
return pendingFetch;
}
@@ -0,0 +1,15 @@
// Provenance: andrebubniak/money-track (fixed).
// repo: andrebubniak/money-track
// commit: 4d4a5b063278c8b6697c3faae133d7c39fcd01c0
// parent: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
// commit_url: https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0
// cve:
// license: MIT
// function: isCategoryIcon
// relpath: src/lib/category-icons.ts
// provenance: agent
// mechanism: prototype_pollution
export function isCategoryIcon(value: string): value is keyof typeof CATEGORY_ICONS {
return Object.hasOwn(CATEGORY_ICONS, value);
}
@@ -0,0 +1,15 @@
// Provenance: andrebubniak/money-track (vuln).
// repo: andrebubniak/money-track
// commit: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
// parent: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
// commit_url: https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0
// cve:
// license: MIT
// function: isCategoryIcon
// relpath: src/lib/category-icons.ts
// provenance: agent
// mechanism: prototype_pollution
export function isCategoryIcon(value: string): value is keyof typeof CATEGORY_ICONS {
return value in CATEGORY_ICONS;
}
@@ -0,0 +1,27 @@
// Provenance: DavideCarvalho/nestjs-filter (fixed).
// repo: DavideCarvalho/nestjs-filter
// commit: aa0e600d05997ea3d77538ea1c2db427c439f2e8
// parent: d899b40d3466f2ffbe9f01c4d49267412401f078
// commit_url: https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8
// cve:
// license: MIT
// function: normalizeInput
// relpath: packages/core/src/input/normalizer.ts
// provenance: agent
// mechanism: prototype_pollution
export function normalizeInput(input: unknown, options: NormalizeOptions): Record<string, unknown> {
if (input == null || typeof input !== 'object') return {};
const norm = pickNormalizer(options.normalizer);
const drop = options.dropId === true;
const out: Record<string, unknown> = {};
for (const [rawKey, value] of Object.entries(input as Record<string, unknown>)) {
if (BLOCKED_KEYS.has(rawKey)) continue;
let key = norm(rawKey);
if (BLOCKED_KEYS.has(key)) continue;
if (drop) key = stripId(key);
if (key.length === 0) continue;
out[key] = value;
}
return out;
}
@@ -0,0 +1,25 @@
// Provenance: DavideCarvalho/nestjs-filter (vuln).
// repo: DavideCarvalho/nestjs-filter
// commit: d899b40d3466f2ffbe9f01c4d49267412401f078
// parent: d899b40d3466f2ffbe9f01c4d49267412401f078
// commit_url: https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8
// cve:
// license: MIT
// function: normalizeInput
// relpath: packages/core/src/input/normalizer.ts
// provenance: agent
// mechanism: prototype_pollution
export function normalizeInput(input: unknown, options: NormalizeOptions): Record<string, unknown> {
if (input == null || typeof input !== 'object') return {};
const norm = pickNormalizer(options.normalizer);
const drop = options.dropId === true;
const out: Record<string, unknown> = {};
for (const [rawKey, value] of Object.entries(input as Record<string, unknown>)) {
let key = norm(rawKey);
if (drop) key = stripId(key);
if (key.length === 0) continue;
out[key] = value;
}
return out;
}
@@ -0,0 +1,72 @@
// Provenance: Sachin-Salgar/NEW_ERP_FINAL (fixed).
// repo: Sachin-Salgar/NEW_ERP_FINAL
// commit: 6e9644c81ce3fb356669157182a5ef09a70c4b59
// parent: 08976c5d7a07b0663669b875b4507446199f85d7
// commit_url: https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59
// cve:
// license: Apache-2.0
// function: origin
// relpath: src/presentation/http/app.ts
// provenance: agent
// mechanism: permissive_default
export async function createApplication(config: AppConfig, providedPool?: Pool): Promise<FastifyInstance> {
const app = Fastify({
logger: createLogger(config),
requestIdHeader: 'x-request-id',
requestIdLogLabel: 'requestId',
ignoreTrailingSlash: true,
ajv: {
customOptions: {
allErrors: true,
coerceTypes: true,
removeAdditional: false,
},
},
});
const pool = providedPool ?? createDatabasePool(config);
const repository = new IdentityAwarePostgresPlatformRepository(pool);
const passwordHasher = new BcryptPasswordHasher();
const jwtTokenService = new JwtTokenService(config);
const authService = new AuthenticationService(repository, passwordHasher, jwtTokenService);
const authorizationService = new AuthorizationService(repository);
const branchService = new BranchService(repository);
const coreEnterpriseService = new CoreEnterpriseService(repository);
const locationService = new LocationService(repository);
const moduleAccessService = new ModuleAccessService(pool);
const registrationService = new UserRegistrationService(repository, passwordHasher);
const tenantMembershipService = new TenantMembershipService(repository);
app.decorate('appConfig', config);
app.decorate('authService', authService);
app.decorate('authorizationService', authorizationService);
app.decorate('branchService', branchService);
app.decorate('coreEnterpriseService', coreEnterpriseService);
app.decorate('locationService', locationService);
app.decorate('moduleAccessService', moduleAccessService);
app.decorate('registrationService', registrationService);
app.decorate('jwtTokenService', jwtTokenService);
app.decorate('tenantMembershipService', tenantMembershipService);
await app.register(cors, {
origin: (origin, callback) => {
callback(null, isCorsOriginAllowed(config, origin));
},
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-tenant-id'],
credentials: true,
optionsSuccessStatus: 204,
});
app.setErrorHandler(buildErrorHandler(config));
await app.register(healthRoutes, { prefix: config.API_PREFIX });
await app.register(authRoutes, { prefix: config.API_PREFIX });
await app.register(rbacRoutes, { prefix: config.API_PREFIX });
await app.register(branchRoutes, { prefix: config.API_PREFIX });
await app.register(coreEnterpriseRoutes, { prefix: config.API_PREFIX });
await app.register(locationRoutes, { prefix: config.API_PREFIX });
return app;
}
@@ -0,0 +1,72 @@
// Provenance: Sachin-Salgar/NEW_ERP_FINAL (vuln).
// repo: Sachin-Salgar/NEW_ERP_FINAL
// commit: 08976c5d7a07b0663669b875b4507446199f85d7
// parent: 08976c5d7a07b0663669b875b4507446199f85d7
// commit_url: https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59
// cve:
// license: Apache-2.0
// function: origin
// relpath: src/presentation/http/app.ts
// provenance: agent
// mechanism: permissive_default
export async function createApplication(config: AppConfig, providedPool?: Pool): Promise<FastifyInstance> {
const app = Fastify({
logger: createLogger(config),
requestIdHeader: 'x-request-id',
requestIdLogLabel: 'requestId',
ignoreTrailingSlash: true,
ajv: {
customOptions: {
allErrors: true,
coerceTypes: true,
removeAdditional: false,
},
},
});
const pool = providedPool ?? createDatabasePool(config);
const repository = new IdentityAwarePostgresPlatformRepository(pool);
const passwordHasher = new BcryptPasswordHasher();
const jwtTokenService = new JwtTokenService(config);
const authService = new AuthenticationService(repository, passwordHasher, jwtTokenService);
const authorizationService = new AuthorizationService(repository);
const branchService = new BranchService(repository);
const coreEnterpriseService = new CoreEnterpriseService(repository);
const locationService = new LocationService(repository);
const moduleAccessService = new ModuleAccessService(pool);
const registrationService = new UserRegistrationService(repository, passwordHasher);
const tenantMembershipService = new TenantMembershipService(repository);
app.decorate('appConfig', config);
app.decorate('authService', authService);
app.decorate('authorizationService', authorizationService);
app.decorate('branchService', branchService);
app.decorate('coreEnterpriseService', coreEnterpriseService);
app.decorate('locationService', locationService);
app.decorate('moduleAccessService', moduleAccessService);
app.decorate('registrationService', registrationService);
app.decorate('jwtTokenService', jwtTokenService);
app.decorate('tenantMembershipService', tenantMembershipService);
await app.register(cors, {
origin: (origin, callback) => {
callback(null, isCorsOriginAllowed(config, origin));
},
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-tenant-id'],
credentials: true,
optionsSuccessStatus: 204,
});
app.setErrorHandler(buildErrorHandler(config));
await app.register(healthRoutes, { prefix: config.API_PREFIX });
await app.register(authRoutes, { prefix: config.API_PREFIX });
await app.register(rbacRoutes, { prefix: config.API_PREFIX });
await app.register(branchRoutes, { prefix: config.API_PREFIX });
await app.register(coreEnterpriseRoutes, { prefix: config.API_PREFIX });
await app.register(locationRoutes, { prefix: config.API_PREFIX });
return app;
}
@@ -0,0 +1,100 @@
// Provenance: Irnhakim/nimestream (fixed).
// repo: Irnhakim/nimestream
// commit: d17f535bf3012041b056ff3aa991ff6cfa198e43
// parent: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
// commit_url: https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43
// cve:
// license: MIT
// function: GET
// relpath: app/api/img/route.js
// provenance: agent
// mechanism: source_reaches_sink
export async function GET(request) {
const { searchParams } = new URL(request.url);
const imageUrl = searchParams.get('url');
if (!imageUrl) {
return new Response('Missing url parameter', { status: 400 });
}
// Only allow proxying images from allowed domains for security
const allowed = [
'otakudesu.blog', 'otakudesu.cloud', 'otakudesu.ltd',
'i3.wp.com', 'i2.wp.com', 'i1.wp.com', 'i0.wp.com',
'cdn.otakudesu', 'kusonime.com', 'wp-content',
'oploverz.ac', 'oploverz.site', 'backapi.oploverz', 'alqanime.net',
'anichin.cafe', 'samehadaku', 'animasu', 'zoronime', 'anoboy', 'nimegami', 'animeindo', 'animekuindo', 'winbu', 'kuramanime', 'animekompi', 'donghub', 'dramabox'
];
let parsedUrl;
try {
parsedUrl = new URL(imageUrl);
} catch (e) {
return new Response('Invalid URL', { status: 400 });
}
const hostname = parsedUrl.hostname;
const isAllowed = allowed.some(domain =>
hostname === domain || hostname.endsWith(`.${domain}`)
);
if (!isAllowed) {
return new Response('Forbidden', { status: 403 });
}
// Determine proper referer
let referer = `${BASE_URL}/`;
if (imageUrl.includes('kusonime.com')) {
referer = 'https://kusonime.com/';
} else if (imageUrl.includes('oploverz.ac') || imageUrl.includes('oploverz.site')) {
referer = 'https://oploverz.site/';
} else if (imageUrl.includes('alqanime.net')) {
referer = 'https://alqanime.net/';
} else if (imageUrl.includes('anichin.cafe')) {
referer = 'https://anichin.cafe/';
} else if (imageUrl.includes('samehadaku')) {
referer = 'https://samehadaku.vip/';
} else if (imageUrl.includes('animasu')) {
referer = 'https://animasu.cc/';
} else if (imageUrl.includes('kuramanime')) {
referer = 'https://kuramanime.net/';
}
try {
// Add abort controller to prevent long timeout waits
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 4000); // 4 seconds timeout limit
const response = await fetch(imageUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Referer': referer,
'Accept': 'image/avif,image/webp,image/apng,image/*,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
},
signal: controller.signal,
cache: 'no-store',
});
clearTimeout(timeoutId);
if (!response.ok) {
return new Response('Failed to fetch source image', { status: response.status });
}
const contentType = response.headers.get('content-type') || 'image/jpeg';
const imageBuffer = await response.arrayBuffer();
return new Response(imageBuffer, {
status: 200,
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=86400, stale-while-revalidate=43200',
'Access-Control-Allow-Origin': '*',
},
});
} catch (err) {
console.error('Image proxy error:', err.message);
return new Response('Error loading image', { status: 500 });
}
}
@@ -0,0 +1,90 @@
// Provenance: Irnhakim/nimestream (vuln).
// repo: Irnhakim/nimestream
// commit: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
// parent: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
// commit_url: https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43
// cve:
// license: MIT
// function: GET
// relpath: app/api/img/route.js
// provenance: agent
// mechanism: source_reaches_sink
export async function GET(request) {
const { searchParams } = new URL(request.url);
const imageUrl = searchParams.get('url');
if (!imageUrl) {
return new Response('Missing url parameter', { status: 400 });
}
// Only allow proxying images from allowed domains for security
const allowed = [
'otakudesu.blog', 'otakudesu.cloud', 'otakudesu.ltd',
'i3.wp.com', 'i2.wp.com', 'i1.wp.com', 'i0.wp.com',
'cdn.otakudesu', 'kusonime.com', 'wp-content',
'oploverz.ac', 'oploverz.site', 'backapi.oploverz', 'alqanime.net',
'anichin.cafe', 'samehadaku', 'animasu', 'zoronime', 'anoboy', 'nimegami', 'animeindo', 'animekuindo', 'winbu', 'kuramanime', 'animekompi', 'donghub', 'dramabox'
];
const isAllowed = allowed.some(domain => imageUrl.includes(domain));
if (!isAllowed) {
return new Response('Forbidden', { status: 403 });
}
// Determine proper referer
let referer = `${BASE_URL}/`;
if (imageUrl.includes('kusonime.com')) {
referer = 'https://kusonime.com/';
} else if (imageUrl.includes('oploverz.ac') || imageUrl.includes('oploverz.site')) {
referer = 'https://oploverz.site/';
} else if (imageUrl.includes('alqanime.net')) {
referer = 'https://alqanime.net/';
} else if (imageUrl.includes('anichin.cafe')) {
referer = 'https://anichin.cafe/';
} else if (imageUrl.includes('samehadaku')) {
referer = 'https://samehadaku.vip/';
} else if (imageUrl.includes('animasu')) {
referer = 'https://animasu.cc/';
} else if (imageUrl.includes('kuramanime')) {
referer = 'https://kuramanime.net/';
}
try {
// Add abort controller to prevent long timeout waits
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 4000); // 4 seconds timeout limit
const response = await fetch(imageUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Referer': referer,
'Accept': 'image/avif,image/webp,image/apng,image/*,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
},
signal: controller.signal,
cache: 'no-store',
});
clearTimeout(timeoutId);
if (!response.ok) {
// Fallback redirect to direct URL if fetch failed but URL is reachable in browser
return Response.redirect(imageUrl, 302);
}
const contentType = response.headers.get('content-type') || 'image/jpeg';
const imageBuffer = await response.arrayBuffer();
return new Response(imageBuffer, {
status: 200,
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=86400, stale-while-revalidate=43200',
'Access-Control-Allow-Origin': '*',
},
});
} catch (err) {
console.error('Image proxy error, falling back to direct redirect:', err.message);
return Response.redirect(imageUrl, 302);
}
}
@@ -0,0 +1,28 @@
# Provenance: HHHHHejia/openniw (fixed).
# repo: HHHHHejia/openniw
# commit: 0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
# parent: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
# commit_url: https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
# cve:
# license: MIT
# function: get_job
# relpath: backend/app/routers/jobs.py
# provenance: agent
# mechanism: identity_from_request_body
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
job = await jobs_service.get(job_id)
if job is None:
raise HTTPException(404, "Job not found")
# Authorization: case-bound jobs are visible only to the case owner;
# caseless jobs (free evaluations) are served by the public route only.
if job.get("case_id") is None:
raise HTTPException(404, "Job not found")
await auth.case_owned_by(str(job["case_id"]), user)
return {
"id": str(job["id"]),
"kind": job["kind"],
"status": job["status"],
"result": job["result"],
"error": job["error"],
}
@@ -0,0 +1,23 @@
# Provenance: HHHHHejia/openniw (vuln).
# repo: HHHHHejia/openniw
# commit: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
# parent: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
# commit_url: https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
# cve:
# license: MIT
# function: get_job
# relpath: backend/app/routers/jobs.py
# provenance: agent
# mechanism: identity_from_request_body
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
job = await jobs_service.get(job_id)
if job is None:
raise HTTPException(404, "Job not found")
return {
"id": str(job["id"]),
"kind": job["kind"],
"status": job["status"],
"result": job["result"],
"error": job["error"],
}
@@ -0,0 +1,28 @@
# Provenance: ziyuzuo/openniw (fixed).
# repo: ziyuzuo/openniw
# commit: b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
# parent: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
# commit_url: https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
# cve:
# license: MIT
# function: get_job
# relpath: backend/app/routers/jobs.py
# provenance: agent
# mechanism: identity_from_request_body
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
job = await jobs_service.get(job_id)
if job is None:
raise HTTPException(404, "Job not found")
# Authorization: case-bound jobs are visible only to the case owner;
# caseless jobs (free evaluations) are served by the public route only.
if job.get("case_id") is None:
raise HTTPException(404, "Job not found")
await auth.case_owned_by(str(job["case_id"]), user)
return {
"id": str(job["id"]),
"kind": job["kind"],
"status": job["status"],
"result": job["result"],
"error": job["error"],
}
@@ -0,0 +1,23 @@
# Provenance: ziyuzuo/openniw (vuln).
# repo: ziyuzuo/openniw
# commit: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
# parent: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
# commit_url: https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
# cve:
# license: MIT
# function: get_job
# relpath: backend/app/routers/jobs.py
# provenance: agent
# mechanism: identity_from_request_body
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
job = await jobs_service.get(job_id)
if job is None:
raise HTTPException(404, "Job not found")
return {
"id": str(job["id"]),
"kind": job["kind"],
"status": job["status"],
"result": job["result"],
"error": job["error"],
}
@@ -0,0 +1,82 @@
// Provenance: ZUENS2020/overleaf-with-claude (fixed).
// repo: ZUENS2020/overleaf-with-claude
// commit: 3980b9e5806defb63e45ae2696e6c1899f3a8431
// parent: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
// commit_url: https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431
// cve:
// license: AGPL-3.0
// function: exportProject
// relpath: services/web/app/src/Features/Exports/ExportsController.mjs
// provenance: agent
// mechanism: identity_from_request_body
import { expressify } from '@overleaf/promise-utils'
import SessionManager from '../Authentication/SessionManager.mjs'
import logger from '@overleaf/logger'
import OError from '@overleaf/o-error'
import settings from '@overleaf/settings'
async function exportProject(req, res, next) {
const { project_id: projectId, brand_variation_id: brandVariationId } =
req.params
const userId = SessionManager.getLoggedInUserId(req.session)
const exportParams = {
project_id: projectId,
brand_variation_id: brandVariationId,
user_id: userId,
}
if (req.body) {
if (req.body.firstName) {
exportParams.first_name = req.body.firstName.trim()
}
if (req.body.lastName) {
exportParams.last_name = req.body.lastName.trim()
}
// additional parameters for gallery exports
if (req.body.title) {
exportParams.title = req.body.title.trim()
}
if (req.body.description) {
exportParams.description = req.body.description.trim()
}
if (req.body.author) {
exportParams.author = req.body.author.trim()
}
if (req.body.license) {
exportParams.license = req.body.license.trim()
}
if (req.body.showSource != null) {
exportParams.show_source = req.body.showSource
}
}
try {
const exportData = await ExportsHandler.exportProject(exportParams)
logger.debug(
{
userId,
projectId,
brandVariationId,
exportV1Id: exportData.v1_id,
},
'exported project'
)
return res.json({
export_v1_id: exportData.v1_id,
token: exportData.token,
message: exportData.message,
})
} catch (err) {
const info = OError.getFullInfo(err)
if (info?.forwardResponse) {
logger.debug(
{ responseError: info.forwardResponse },
'forwarding response'
)
const statusCode = info.forwardResponse.status || 500
return res.status(statusCode).json(info.forwardResponse)
}
throw err
}
}
@@ -0,0 +1,80 @@
// Provenance: ZUENS2020/overleaf-with-claude (vuln).
// repo: ZUENS2020/overleaf-with-claude
// commit: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
// parent: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
// commit_url: https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431
// cve:
// license: AGPL-3.0
// function: exportProject
// relpath: services/web/app/src/Features/Exports/ExportsController.mjs
// provenance: agent
// mechanism: identity_from_request_body
import { expressify } from '@overleaf/promise-utils'
import SessionManager from '../Authentication/SessionManager.mjs'
import logger from '@overleaf/logger'
import OError from '@overleaf/o-error'
async function exportProject(req, res, next) {
const { project_id: projectId, brand_variation_id: brandVariationId } =
req.params
const userId = SessionManager.getLoggedInUserId(req.session)
const exportParams = {
project_id: projectId,
brand_variation_id: brandVariationId,
user_id: userId,
}
if (req.body) {
if (req.body.firstName) {
exportParams.first_name = req.body.firstName.trim()
}
if (req.body.lastName) {
exportParams.last_name = req.body.lastName.trim()
}
// additional parameters for gallery exports
if (req.body.title) {
exportParams.title = req.body.title.trim()
}
if (req.body.description) {
exportParams.description = req.body.description.trim()
}
if (req.body.author) {
exportParams.author = req.body.author.trim()
}
if (req.body.license) {
exportParams.license = req.body.license.trim()
}
if (req.body.showSource != null) {
exportParams.show_source = req.body.showSource
}
}
try {
const exportData = await ExportsHandler.exportProject(exportParams)
logger.debug(
{
userId,
projectId,
brandVariationId,
exportV1Id: exportData.v1_id,
},
'exported project'
)
return res.json({
export_v1_id: exportData.v1_id,
message: exportData.message,
})
} catch (err) {
const info = OError.getFullInfo(err)
if (info?.forwardResponse) {
logger.debug(
{ responseError: info.forwardResponse },
'forwarding response'
)
const statusCode = info.forwardResponse.status || 500
return res.status(statusCode).json(info.forwardResponse)
}
throw err
}
}
@@ -0,0 +1,33 @@
// Provenance: dayflower/popmark (fixed).
// repo: dayflower/popmark
// commit: e5ac407cef37c37178d440541ede301c838640fb
// parent: 31d1ac79b4cfa3118597348e79800a6561115149
// commit_url: https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/lexical-markdown/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
// popmark patch: guard against prototype pollution (CodeQL).
if (key === "__proto__" || key === "constructor" || key === "prototype") {
continue;
}
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
@@ -0,0 +1,29 @@
// Provenance: dayflower/popmark (vuln).
// repo: dayflower/popmark
// commit: 31d1ac79b4cfa3118597348e79800a6561115149
// parent: 31d1ac79b4cfa3118597348e79800a6561115149
// commit_url: https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb
// cve:
// license: MIT
// function: deepMergeInto
// relpath: src/lexical-markdown/config/editorConfig.ts
// provenance: agent
// mechanism: prototype_pollution
function deepMergeInto(
target: Record<string, unknown>,
source: Record<string, unknown>,
): Record<string, unknown> {
for (const key of Object.keys(source)) {
const sourceValue = source[key];
if (sourceValue === undefined) continue;
if (isPlainObject(sourceValue)) {
const targetValue = target[key];
const nested = isPlainObject(targetValue) ? targetValue : {};
target[key] = deepMergeInto(nested, sourceValue);
} else {
target[key] = sourceValue;
}
}
return target;
}
@@ -0,0 +1,51 @@
// Provenance: DevilsDev/rag-pipeline-utils (fixed).
// repo: DevilsDev/rag-pipeline-utils
// commit: 76e5f0a94d6803d0e463d26a61cedb7da90857a7
// parent: ba587867118f703632ff2dc63c4feb8ad6793420
// commit_url: https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7
// cve:
// license: MIT
// function: handleConfigSet
// relpath: src/cli/handlers/config-handler.js
// provenance: agent
// mechanism: prototype_pollution
async function handleConfigSet(globalOptions, key, value) {
try {
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
// Set value using dot notation
const keys = key.split(".");
const forbidden = new Set(["__proto__", "constructor", "prototype"]);
if (keys.some((k) => forbidden.has(k))) {
logger.error("Invalid configuration key: contains restricted property");
process.exit(1);
}
let current = config;
for (let i = 0; i < keys.length - 1; i++) {
if (!current[keys[i]]) {
current[keys[i]] = {};
}
current = current[keys[i]];
}
// Parse value
let parsedValue;
try {
parsedValue = JSON.parse(value);
} catch (error) {
parsedValue = value; // Keep as string
}
current[keys[keys.length - 1]] = parsedValue;
// Save configuration
await fs.writeFile(globalOptions.config, JSON.stringify(config, null, 2));
console.log("✅ Configuration updated");
} catch (error) {
logger.error("❌ Failed to set configuration:", error.message);
process.exit(1);
}
}
@@ -0,0 +1,45 @@
// Provenance: DevilsDev/rag-pipeline-utils (vuln).
// repo: DevilsDev/rag-pipeline-utils
// commit: ba587867118f703632ff2dc63c4feb8ad6793420
// parent: ba587867118f703632ff2dc63c4feb8ad6793420
// commit_url: https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7
// cve:
// license: MIT
// function: handleConfigSet
// relpath: src/cli/handlers/config-handler.js
// provenance: agent
// mechanism: prototype_pollution
async function handleConfigSet(globalOptions, key, value) {
try {
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
// Set value using dot notation
const keys = key.split(".");
let current = config;
for (let i = 0; i < keys.length - 1; i++) {
if (!current[keys[i]]) {
current[keys[i]] = {};
}
current = current[keys[i]];
}
// Parse value
let parsedValue;
try {
parsedValue = JSON.parse(value);
} catch (error) {
parsedValue = value; // Keep as string
}
current[keys[keys.length - 1]] = parsedValue;
// Save configuration
await fs.writeFile(globalOptions.config, JSON.stringify(config, null, 2));
console.log("✅ Configuration updated");
} catch (error) {
logger.error("❌ Failed to set configuration:", error.message);
process.exit(1);
}
}
+977
View File
@@ -0,0 +1,977 @@
# agent-vfc candidate recipes from agent-trailer security-fix commits (build_recipes.py).
# reviewer = "pending" means a human has not yet confirmed the vulnerability and mechanism.
[[recipe]]
name = "academic-based-qoder-app-a79ddb"
host = "github"
repo = "1173591564/academic-based-qoder"
parent = "8170f0377fe64d1ec2e35769d4ce3d0634d97cef"
commit = "a79ddb90def54e91f7507cbf6b1548b224d642aa"
path = "services/proxy-hub/backend/proxy_hub/app.py"
mode = "hunk"
language = "python"
relpath = "services/proxy-hub/backend/proxy_hub/app.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "academic-based-qoder"
trailer = "Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>"
reviewer = "pending"
evidence = "fix(hub): allow DSH token validation CORS"
commit_url = "https://github.com/1173591564/academic-based-qoder/commit/a79ddb90def54e91f7507cbf6b1548b224d642aa"
split = "train"
[[recipe]]
name = "anastasios-pw-session-14ec1a"
host = "github"
repo = "Anas329796/Anastasios"
parent = "adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb"
commit = "14ec1ac50f9e4e255d875236d30129c6207401d4"
path = "extensions/browser/src/browser/pw-session.ts"
mode = "hunk"
language = "typescript"
relpath = "extensions/browser/src/browser/pw-session.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-918"
class = "server-side request forgery"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "Anastasios"
trailer = "Co-authored-by: Devin Robison <[email protected]>"
reviewer = "pending"
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
commit_url = "https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4"
split = "holdout"
[[recipe]]
name = "arsnova-eu-httpcors-9bcba4"
host = "github"
repo = "kqc-real/arsnova.eu"
parent = "2ae60c434f3fb80f91807a2ec485ee1a7ec76bd2"
commit = "9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df"
path = "apps/backend/src/lib/httpCors.ts"
mode = "hunk"
language = "typescript"
relpath = "apps/backend/src/lib/httpCors.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "arsnova.eu"
trailer = "Co-authored-by: Cursor <[email protected]>"
reviewer = "pending"
evidence = "fix(security): Produktions-CORS auf Same-Origin begrenzen (#143)"
commit_url = "https://github.com/kqc-real/arsnova.eu/commit/9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df"
split = "train"
[[recipe]]
name = "astroclaw-pw-session-1553a8"
host = "github"
repo = "P1R4N351/astroclaw"
parent = "d3eed2dc01328f21dd404477bb28e2740fa371a4"
commit = "1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
path = "extensions/browser/src/browser/pw-session.ts"
mode = "hunk"
language = "typescript"
relpath = "extensions/browser/src/browser/pw-session.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-918"
class = "server-side request forgery"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "astroclaw"
trailer = "Co-authored-by: Devin Robison <[email protected]>"
reviewer = "pending"
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
commit_url = "https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
split = "holdout"
[[recipe]]
name = "capgo-app-apptabs-7d73fd"
host = "github"
repo = "Cap-go/capgo.app"
parent = "415ea4e19d7da19a3f8b0cd0bba541d60b902522"
commit = "7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7"
path = "src/constants/appTabs.ts"
mode = "hunk"
language = "typescript"
relpath = "src/constants/appTabs.ts"
license = "AGPL-3.0"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "capgo.app"
trailer = "Co-authored-by: Cursor <[email protected]>"
reviewer = "pending"
evidence = "fix(notifications): harden API CORS and mark console tab as beta (#2623)"
commit_url = "https://github.com/Cap-go/capgo.app/commit/7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7"
split = "train"
[[recipe]]
name = "capgo-app-hono-4dadd2"
host = "github"
repo = "Cap-go/capgo.app"
parent = "8c0ac7e233946abd8dc26581b871e9fcd0928899"
commit = "4dadd2580d02213d227a331eee0232aa59859b59"
path = "supabase/functions/_backend/utils/hono.ts"
mode = "hunk"
language = "typescript"
relpath = "supabase/functions/_backend/utils/hono.ts"
license = "AGPL-3.0"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "capgo.app"
trailer = "Co-authored-by: Cursor <[email protected]>"
reviewer = "pending"
evidence = "fix(api): CORS for Capacitor localhost WebView (#3105)"
commit_url = "https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59"
split = "holdout"
[[recipe]]
name = "dailyforge-server-ed1470"
host = "github"
repo = "Annamdevula-Nissi-Grace/Dailyforge"
parent = "adc164d6e87ff735a3ea5637a2febfd3217e168a"
commit = "ed1470814a108bd725c8b27bd9d86cf95a979a96"
path = "backend/src/server.js"
mode = "hunk"
language = "javascript"
relpath = "backend/src/server.js"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "Dailyforge"
trailer = "Co-authored-by: Copilot <[email protected]>"
reviewer = "pending"
evidence = "Fix: add localhost fallback for CORS origin (#172)"
commit_url = "https://github.com/Annamdevula-Nissi-Grace/Dailyforge/commit/ed1470814a108bd725c8b27bd9d86cf95a979a96"
split = "train"
[[recipe]]
name = "dnf-plugin-anyrepo-config-26d19a"
host = "github"
repo = "jfut/dnf-plugin-anyrepo"
parent = "33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a"
commit = "26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
path = "dnf_plugin_anyrepo/config.py"
mode = "hunk"
language = "python"
relpath = "dnf_plugin_anyrepo/config.py"
license = "Apache-2.0"
cve = ""
year = 2026
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "agent"
origin = "github-agent-trailer"
project = "dnf-plugin-anyrepo"
trailer = "Co-authored-by: Codex <[email protected]>"
reviewer = "pending"
evidence = "fix(config): prevent path traversal in repository names"
commit_url = "https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
split = "holdout"
[[recipe]]
name = "edutrace-page-ee7ba2"
host = "github"
repo = "jardimdesoftware/edutrace"
parent = "c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd"
commit = "ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
path = "front/src/app/editar-anamnese/page.tsx"
mode = "hunk"
language = "typescript"
relpath = "front/src/app/editar-anamnese/page.tsx"
license = "Apache-2.0"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "edutrace"
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
reviewer = "pending"
evidence = "fix(front): impedir prototype pollution nos handlers de formulário aninhado"
commit_url = "https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
split = "train"
[[recipe]]
name = "etoj-index-605274"
host = "github"
repo = "Eternity-Sky/_ETOJ"
parent = "b0c020fd9ca0204630fca8a857d6fc1b1497bd5b"
commit = "6052743d477eeff62e32553c2790785d3f52c641"
path = "api/src/index.ts"
mode = "hunk"
language = "typescript"
relpath = "api/src/index.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "_ETOJ"
trailer = "Generated with [Devin](https://devin.ai)"
reviewer = "pending"
evidence = "Fix CORS: Add PATCH method to allowed methods"
commit_url = "https://github.com/Eternity-Sky/_ETOJ/commit/6052743d477eeff62e32553c2790785d3f52c641"
split = "holdout"
[[recipe]]
name = "etude-lexical-markdown-editorconfig-c61a8b"
host = "github"
repo = "dayflower/etude-lexical-markdown"
parent = "0a2184f59e79a04b1365cd49200026e8f2ffdbd5"
commit = "c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
path = "src/config/editorConfig.ts"
mode = "hunk"
language = "typescript"
relpath = "src/config/editorConfig.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "etude-lexical-markdown"
trailer = "Co-Authored-By: Claude <[email protected]>"
reviewer = "pending"
evidence = "fix: guard deepMergeInto against prototype pollution"
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
split = "train"
[[recipe]]
name = "etude-lexical-markdown-editorconfig-db4f54"
host = "github"
repo = "dayflower/etude-lexical-markdown"
parent = "1c865815d05b072f4973388c3ac66b6696d9efde"
commit = "db4f54b1ab80ad596de6425e84f90aa781c49999"
path = "src/config/editorConfig.ts"
mode = "hunk"
language = "typescript"
relpath = "src/config/editorConfig.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "etude-lexical-markdown"
trailer = "Co-Authored-By: Claude <[email protected]>"
reviewer = "pending"
evidence = "fix: make prototype pollution guard recognizable by CodeQL"
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999"
split = "holdout"
[[recipe]]
name = "gitim-git-cors-proxy-e4c3a4"
host = "github"
repo = "CiferaTeam/GitIM"
parent = "8afa34d45e119164abec0b76ed77a56f442749a8"
commit = "e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6"
path = "products/gitim/frontend/src/lib/git-cors-proxy.ts"
mode = "hunk"
language = "typescript"
relpath = "products/gitim/frontend/src/lib/git-cors-proxy.ts"
license = "Apache-2.0"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "GitIM"
trailer = "Co-authored-by: Codex <[email protected]>"
reviewer = "pending"
evidence = "fix(frontend): use gitim cors proxy by default"
commit_url = "https://github.com/CiferaTeam/GitIM/commit/e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6"
split = "train"
[[recipe]]
name = "lensops-kubernetesmanagement-fe4910"
host = "github"
repo = "amitknigam84/lensops"
parent = "9b87ecc3a44a7fe2a5185cca1fe52441647d5748"
commit = "fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
path = "components/KubernetesManagement.tsx"
mode = "hunk"
language = "typescript"
relpath = "components/KubernetesManagement.tsx"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-862"
class = "missing authorization"
mechanism = "missing_auth_guard"
provenance = "agent"
origin = "github-agent-trailer"
project = "lensops"
trailer = "Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
reviewer = "pending"
evidence = "Fix missing auth header on namespaces API call"
commit_url = "https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
split = "holdout"
[[recipe]]
name = "market-cap-route-4f8ae9"
host = "github"
repo = "navaneethbv/market-cap"
parent = "fec6f024ce72c9c47b61cbac6ce7a35cb2280602"
commit = "4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
path = "app/auth/confirm/route.ts"
mode = "hunk"
language = "typescript"
relpath = "app/auth/confirm/route.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-601"
class = "open redirect"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "market-cap"
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
reviewer = "pending"
evidence = "Fix open redirects on the auth next param"
commit_url = "https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
split = "train"
[[recipe]]
name = "melodix-playerprovider-089931"
host = "github"
repo = "alexshao3/melodix"
parent = "c074fc7413338aefcbea3170ef4d3ba486a8a4b7"
commit = "089931ef71ea1e5b7586520baf1a5498e2f05b13"
path = "apps/miniapp/src/components/PlayerProvider.tsx"
mode = "hunk"
language = "typescript"
relpath = "apps/miniapp/src/components/PlayerProvider.tsx"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "melodix"
trailer = "Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>"
reviewer = "pending"
evidence = "Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors"
commit_url = "https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13"
split = "holdout"
[[recipe]]
name = "mercado-do-vale-news-catalogmetadataservice-9b5fcf"
host = "github"
repo = "handielson/Mercado-do-vale-news"
parent = "70ca282b819ac1d60f4b5e665d224b1043ff1ccc"
commit = "9b5fcf2dae41e56f5f97952266f2d6ba59598598"
path = "services/catalogMetadataService.ts"
mode = "hunk"
language = "typescript"
relpath = "services/catalogMetadataService.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "Mercado-do-vale-news"
trailer = "Co-Authored-By: Codex <[email protected]>"
reviewer = "pending"
evidence = "fix(catalog): avoid metadata cors preflight"
commit_url = "https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598"
split = "train"
[[recipe]]
name = "money-track-category-icons-4d4a5b"
host = "github"
repo = "andrebubniak/money-track"
parent = "add96df6d6a6b61506635c23dbacf6c6cfe24dc2"
commit = "4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
path = "src/lib/category-icons.ts"
mode = "hunk"
language = "typescript"
relpath = "src/lib/category-icons.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "money-track"
trailer = "Co-Authored-By: Claude Sonnet 5 <[email protected]>"
reviewer = "pending"
evidence = "fix(category-icons): use Object.hasOwn to prevent prototype pollution in type guard"
commit_url = "https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
split = "holdout"
[[recipe]]
name = "nestjs-filter-normalizer-aa0e60"
host = "github"
repo = "DavideCarvalho/nestjs-filter"
parent = "d899b40d3466f2ffbe9f01c4d49267412401f078"
commit = "aa0e600d05997ea3d77538ea1c2db427c439f2e8"
path = "packages/core/src/input/normalizer.ts"
mode = "hunk"
language = "typescript"
relpath = "packages/core/src/input/normalizer.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "nestjs-filter"
trailer = "Co-Authored-By: Claude Opus 4.7 <[email protected]>"
reviewer = "pending"
evidence = "fix(core): add prototype pollution guard to normalizeInput"
commit_url = "https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8"
split = "train"
[[recipe]]
name = "new-erp-final-app-6e9644"
host = "github"
repo = "Sachin-Salgar/NEW_ERP_FINAL"
parent = "08976c5d7a07b0663669b875b4507446199f85d7"
commit = "6e9644c81ce3fb356669157182a5ef09a70c4b59"
path = "src/presentation/http/app.ts"
mode = "hunk"
language = "typescript"
relpath = "src/presentation/http/app.ts"
license = "Apache-2.0"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "NEW_ERP_FINAL"
trailer = "Co-authored-by: Copilot <[email protected]>"
reviewer = "pending"
evidence = "fix: allow patch requests through cors"
commit_url = "https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59"
split = "holdout"
[[recipe]]
name = "nimestream-route-d17f53"
host = "github"
repo = "Irnhakim/nimestream"
parent = "0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0"
commit = "d17f535bf3012041b056ff3aa991ff6cfa198e43"
path = "app/api/img/route.js"
mode = "hunk"
language = "javascript"
relpath = "app/api/img/route.js"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-918"
class = "server-side request forgery"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "nimestream"
trailer = "Co-Authored-By: Claude <[email protected]>"
reviewer = "pending"
evidence = "fix: resolve command injection and SSRF/Open Redirect security issues in multiScraper and image proxy API"
commit_url = "https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43"
split = "train"
[[recipe]]
name = "onlook-helper-57ce1c"
host = "github"
repo = "zhcndoc/onlook"
parent = "cb97e012729eca441e09b1503282cb4bc2f4bcfb"
commit = "57ce1ccfacc7e8484cae59013a2b1e34518560e5"
path = "apps/web/client/src/server/api/routers/project/helper.ts"
mode = "hunk"
language = "typescript"
relpath = "apps/web/client/src/server/api/routers/project/helper.ts"
license = "Apache-2.0"
cve = ""
year = 2025
cwe = "CWE-862"
class = "missing authorization"
mechanism = "missing_auth_guard"
provenance = "agent"
origin = "github-agent-trailer"
project = "onlook"
trailer = "Co-Authored-By: Claude <[email protected]>"
reviewer = "pending"
evidence = "Fix CVE-2025-63783: Add authorization checks to project mutation APIs (#3062)"
commit_url = "https://github.com/zhcndoc/onlook/commit/57ce1ccfacc7e8484cae59013a2b1e34518560e5"
split = "holdout"
[[recipe]]
name = "openniw-jobs-0fc947"
host = "github"
repo = "HHHHHejia/openniw"
parent = "4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc"
commit = "0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
path = "backend/app/routers/jobs.py"
mode = "hunk"
language = "python"
relpath = "backend/app/routers/jobs.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-639"
class = "insecure direct object reference"
mechanism = "identity_from_request_body"
provenance = "agent"
origin = "github-agent-trailer"
project = "openniw"
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
reviewer = "pending"
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
commit_url = "https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
split = "train"
[[recipe]]
name = "openniw-jobs-b74de3"
host = "github"
repo = "ziyuzuo/openniw"
parent = "98a0c392ba96cd2c4aa746dd6fc2b183f385225e"
commit = "b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
path = "backend/app/routers/jobs.py"
mode = "hunk"
language = "python"
relpath = "backend/app/routers/jobs.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-639"
class = "insecure direct object reference"
mechanism = "identity_from_request_body"
provenance = "agent"
origin = "github-agent-trailer"
project = "openniw"
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
reviewer = "pending"
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
commit_url = "https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
split = "holdout"
[[recipe]]
name = "overleaf-with-claude-exportscontroller-3980b9"
host = "github"
repo = "ZUENS2020/overleaf-with-claude"
parent = "5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed"
commit = "3980b9e5806defb63e45ae2696e6c1899f3a8431"
path = "services/web/app/src/Features/Exports/ExportsController.mjs"
mode = "hunk"
language = "javascript"
relpath = "services/web/app/src/Features/Exports/ExportsController.mjs"
license = "AGPL-3.0"
cve = ""
year = 2026
cwe = "CWE-639"
class = "insecure direct object reference"
mechanism = "identity_from_request_body"
provenance = "agent"
origin = "github-agent-trailer"
project = "overleaf-with-claude"
trailer = "Co-authored-by: briangough <[email protected]>"
reviewer = "pending"
evidence = "Fix IDOR in exports by adding token verification (Issue #31637) (#32883)"
commit_url = "https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431"
split = "train"
[[recipe]]
name = "popmark-editorconfig-e5ac40"
host = "github"
repo = "dayflower/popmark"
parent = "31d1ac79b4cfa3118597348e79800a6561115149"
commit = "e5ac407cef37c37178d440541ede301c838640fb"
path = "src/lexical-markdown/config/editorConfig.ts"
mode = "hunk"
language = "typescript"
relpath = "src/lexical-markdown/config/editorConfig.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "popmark"
trailer = "Co-Authored-By: Claude <[email protected]>"
reviewer = "pending"
evidence = "fix: guard deepMergeInto against prototype pollution"
commit_url = "https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb"
split = "holdout"
[[recipe]]
name = "rag-pipeline-utils-config-handler-76e5f0"
host = "github"
repo = "DevilsDev/rag-pipeline-utils"
parent = "ba587867118f703632ff2dc63c4feb8ad6793420"
commit = "76e5f0a94d6803d0e463d26a61cedb7da90857a7"
path = "src/cli/handlers/config-handler.js"
mode = "hunk"
language = "javascript"
relpath = "src/cli/handlers/config-handler.js"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-1321"
class = "prototype pollution"
mechanism = "prototype_pollution"
provenance = "agent"
origin = "github-agent-trailer"
project = "rag-pipeline-utils"
trailer = "Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>"
reviewer = "pending"
evidence = "fix(security): prevent prototype pollution in config-handler"
commit_url = "https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7"
split = "train"
[[recipe]]
name = "registry-proxy-worker-426847"
host = "github"
repo = "agents-repo/registry-proxy"
parent = "6d5937972510cdb5ebca30607b538fdc2e280094"
commit = "426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
path = "src/worker.js"
mode = "hunk"
language = "javascript"
relpath = "src/worker.js"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "registry-proxy"
trailer = "Co-authored-by: Cursor <[email protected]>"
reviewer = "pending"
evidence = "fix: handle CORS OPTIONS preflight for catalog fetches (#10)"
commit_url = "https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
split = "holdout"
[[recipe]]
name = "rls-alembic-rls-d2b6af"
host = "github"
repo = "DelfinaCare/rls"
parent = "670123485f1c657e9faeb18e633339b6a79e696f"
commit = "d2b6af47347fb285b7a3820a7f2d5dded20907ec"
path = "rls/alembic_rls.py"
mode = "hunk"
language = "python"
relpath = "rls/alembic_rls.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "rls"
trailer = "Co-authored-by: aebrahim <[email protected]>"
reviewer = "pending"
evidence = "Guard against ENABLE ROW LEVEL SECURITY on tables with no policies (#143)"
commit_url = "https://github.com/DelfinaCare/rls/commit/d2b6af47347fb285b7a3820a7f2d5dded20907ec"
split = "train"
[[recipe]]
name = "supplieradvisor-mvp-route-387bcf"
host = "github"
repo = "bigfivefoods/supplieradvisor-mvp"
parent = "a7a9bc260d649ea2e582c07435bfd7d93100647b"
commit = "387bcf40e984a2ee1832ab7beabf0284c5b627d8"
path = "app/api/customers/claims/route.ts"
mode = "hunk"
language = "typescript"
relpath = "app/api/customers/claims/route.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-639"
class = "insecure direct object reference"
mechanism = "identity_from_request_body"
provenance = "agent"
origin = "github-agent-trailer"
project = "supplieradvisor-mvp"
trailer = "Co-authored-by: bigfivefoods <[email protected]>"
reviewer = "pending"
evidence = "Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156)"
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8"
split = "holdout"
[[recipe]]
name = "supplieradvisor-mvp-route-a69e8f"
host = "github"
repo = "bigfivefoods/supplieradvisor-mvp"
parent = "8558538471e4fb10856f8d9a17d2be5ab5c4fb9c"
commit = "a69e8f27c0f4d402573d16f0612b51155bbc46e1"
path = "app/api/customers/opportunities/route.ts"
mode = "hunk"
language = "typescript"
relpath = "app/api/customers/opportunities/route.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-639"
class = "insecure direct object reference"
mechanism = "identity_from_request_body"
provenance = "agent"
origin = "github-agent-trailer"
project = "supplieradvisor-mvp"
trailer = "Co-authored-by: bigfivefoods <[email protected]>"
reviewer = "pending"
evidence = "Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership checks) (#148)"
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1"
split = "train"
[[recipe]]
name = "tools-cli-tools-a96bc0"
host = "github"
repo = "D-sorganization/Tools"
parent = "e735d28b82dd1fbc42c0ae01157b38d1b4c7c864"
commit = "a96bc0502a3dcdac303e4f0152508886e5c35c0a"
path = "src/shared/python/ai/tools/cli_tools.py"
mode = "hunk"
language = "python"
relpath = "src/shared/python/ai/tools/cli_tools.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "Tools"
trailer = "Co-authored-by: dieterolson <[email protected]>"
reviewer = "pending"
evidence = "🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307)"
commit_url = "https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a"
split = "holdout"
[[recipe]]
name = "tools-wsgi-e18686"
host = "github"
repo = "D-sorganization/Tools"
parent = "f34c44a0842ac983e2a984fe7fd985be3ccaf747"
commit = "e18686aaa174a8a4843c07b4727771c92e0f179e"
path = "src/web_applications/unit_converter/wsgi.py"
mode = "hunk"
language = "python"
relpath = "src/web_applications/unit_converter/wsgi.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "agent"
origin = "github-agent-trailer"
project = "Tools"
trailer = "Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
reviewer = "pending"
evidence = "fix(security): validate mesh filenames against path traversal in _download_meshes (#2077) (#2107)"
commit_url = "https://github.com/D-sorganization/Tools/commit/e18686aaa174a8a4843c07b4727771c92e0f179e"
split = "train"
[[recipe]]
name = "trackly-cli-path-diagnostics-1c1aed"
host = "github"
repo = "trackly-app/trackly-cli"
parent = "8d240ad8d7fc114c8f941ad956a2fdf32391ff60"
commit = "1c1aed89b07edb04051830c8f086e02b65e961c6"
path = "lib/path-diagnostics.js"
mode = "hunk"
language = "javascript"
relpath = "lib/path-diagnostics.js"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "agent"
origin = "github-agent-trailer"
project = "trackly-cli"
trailer = "Co-authored-by: Codex <[email protected]>"
reviewer = "pending"
evidence = "fix(apply): report blocked path traversal"
commit_url = "https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6"
split = "holdout"
[[recipe]]
name = "upstreamdrift-local-server-c3a078"
host = "github"
repo = "D-sorganization/UpstreamDrift"
parent = "e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc"
commit = "c3a0787080489b30e2ed0abfac03b51e45da184b"
path = "src/api/local_server.py"
mode = "hunk"
language = "python"
relpath = "src/api/local_server.py"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "agent"
origin = "github-agent-trailer"
project = "UpstreamDrift"
trailer = "Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>"
reviewer = "pending"
evidence = "fix(api): harden local server path traversal (#2805) (#2839)"
commit_url = "https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b"
split = "train"
[[recipe]]
name = "vantalk-firebase-16c3b0"
host = "github"
repo = "NiSeullent/VanTalk"
parent = "7d442bdf537df96c756d47cfc6ce0ccdb3cd8ea7"
commit = "16c3b02875b1f51c3cac1dc185e199978a35985c"
path = "web/src/firebase.ts"
mode = "hunk"
language = "typescript"
relpath = "web/src/firebase.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-798"
class = "hardcoded credentials"
mechanism = "secret_in_client"
provenance = "agent"
origin = "github-agent-trailer"
project = "VanTalk"
trailer = "Co-authored-by: Cursor <[email protected]>"
reviewer = "pending"
evidence = "fix(security): load Firebase API key from env, remove hardcoded secret"
commit_url = "https://github.com/NiSeullent/VanTalk/commit/16c3b02875b1f51c3cac1dc185e199978a35985c"
split = "holdout"
[[recipe]]
name = "waggledance-swarm-ssrf-host-guard-9a4548"
host = "github"
repo = "Ahkeratmehilaiset/waggledance-swarm"
parent = "934b939f1cca5259eaf807db3319eb97b90d8d80"
commit = "9a454843aa35332ff2eb3106023eee0c4b5e444b"
path = "waggledance/core/v3_13_0/ssrf_host_guard.py"
mode = "hunk"
language = "python"
relpath = "waggledance/core/v3_13_0/ssrf_host_guard.py"
license = "Apache-2.0"
cve = ""
year = 2026
cwe = "CWE-918"
class = "server-side request forgery"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "waggledance-swarm"
trailer = "Co-authored-by: codex-lead-1 <[email protected]>"
reviewer = "pending"
evidence = "fix(ssrf): reject bare-string allowed hosts (#1460)"
commit_url = "https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b"
split = "train"
[[recipe]]
name = "workers-research-utils-209444"
host = "github"
repo = "G4brym/workers-research"
parent = "eab923ad3099c01b002fbd6be7cf994614bbdee4"
commit = "209444eb61cc564c2d6b43267256f85fe3e5e30e"
path = "src/utils.ts"
mode = "hunk"
language = "typescript"
relpath = "src/utils.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-89"
class = "sql injection"
mechanism = "source_reaches_sink"
provenance = "agent"
origin = "github-agent-trailer"
project = "workers-research"
trailer = "Co-Authored-By: Claude Opus 4.6 <[email protected]>"
reviewer = "pending"
evidence = "Fix SQL injection in search by using parameterized queries (#41)"
commit_url = "https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e"
split = "holdout"
[[recipe]]
name = "zoonk-origin-bfbf67"
host = "github"
repo = "zoonk/zoonk"
parent = "2604269350bff51f58572c133b45010cb0976a5a"
commit = "bfbf670ccb41d63c407d32c51bd26e626a174f31"
path = "packages/utils/src/origin.ts"
mode = "hunk"
language = "typescript"
relpath = "packages/utils/src/origin.ts"
license = "MIT"
cve = ""
year = 2026
cwe = "CWE-16"
class = "permissive default"
mechanism = "permissive_default"
provenance = "agent"
origin = "github-agent-trailer"
project = "zoonk"
trailer = "Co-authored-by: Codex <[email protected]>"
reviewer = "pending"
evidence = "fix(api): allow staging cors from previews (#1559)"
commit_url = "https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31"
split = "train"
@@ -0,0 +1,43 @@
// Provenance: agents-repo/registry-proxy (fixed).
// repo: agents-repo/registry-proxy
// commit: 426847899eb2ee94ae4e5a3aacc50423e36d2dc8
// parent: 6d5937972510cdb5ebca30607b538fdc2e280094
// commit_url: https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8
// cve:
// license: MIT
// function: buildUpstreamRequest
// relpath: src/worker.js
// provenance: agent
// mechanism: permissive_default
function buildUpstreamRequest(target, env, requestHeaders) {
const headers = new Headers();
const requestAccept = requestHeaders.get("Accept") || "*/*";
headers.set("User-Agent", UPSTREAM_USER_AGENT);
const ifNoneMatch = requestHeaders.get("If-None-Match");
if (ifNoneMatch) {
headers.set("If-None-Match", ifNoneMatch);
}
const ifModifiedSince = requestHeaders.get("If-Modified-Since");
if (ifModifiedSince) {
headers.set("If-Modified-Since", ifModifiedSince);
}
if (env.GITHUB_TOKEN) {
headers.set("Accept", "application/vnd.github.raw");
headers.set("Authorization", `Bearer ${env.GITHUB_TOKEN}`);
return {
url: buildContentsApiUrl(target.ref, target.targetPath),
headers,
};
}
headers.set("Accept", requestAccept);
return {
url: buildUpstreamUrl(target.ref, target.targetPath),
headers,
};
}
@@ -0,0 +1,33 @@
// Provenance: agents-repo/registry-proxy (vuln).
// repo: agents-repo/registry-proxy
// commit: 6d5937972510cdb5ebca30607b538fdc2e280094
// parent: 6d5937972510cdb5ebca30607b538fdc2e280094
// commit_url: https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8
// cve:
// license: MIT
// function: buildUpstreamRequest
// relpath: src/worker.js
// provenance: agent
// mechanism: permissive_default
function buildUpstreamRequest(target, env, requestHeaders) {
const headers = new Headers();
const requestAccept = requestHeaders.get("Accept") || "*/*";
headers.set("User-Agent", UPSTREAM_USER_AGENT);
if (env.GITHUB_TOKEN) {
headers.set("Accept", "application/vnd.github.raw");
headers.set("Authorization", `Bearer ${env.GITHUB_TOKEN}`);
return {
url: buildContentsApiUrl(target.ref, target.targetPath),
headers,
};
}
headers.set("Accept", requestAccept);
return {
url: buildUpstreamUrl(target.ref, target.targetPath),
headers,
};
}
@@ -0,0 +1,69 @@
// Provenance: bigfivefoods/supplieradvisor-mvp (fixed).
// repo: bigfivefoods/supplieradvisor-mvp
// commit: 387bcf40e984a2ee1832ab7beabf0284c5b627d8
// parent: a7a9bc260d649ea2e582c07435bfd7d93100647b
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8
// cve:
// license: MIT
// function: PATCH
// relpath: app/api/customers/claims/route.ts
// provenance: agent
// mechanism: identity_from_request_body
export async function PATCH(request: NextRequest) {
try {
const body = await request.json();
const claimId = Number(body.id);
const companyId = Number(body.companyId);
if (!Number.isFinite(claimId) || claimId <= 0) {
return NextResponse.json({ error: 'id required' }, { status: 400 });
}
if (!Number.isFinite(companyId) || companyId <= 0) {
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
}
const _gate = await requireCompanyAccess(request, companyId, { legacyPrivyUserId: legacyPrivyFrom(request) });
if (!_gate.ok) return _gate.response;
const supabase = getSupabaseServer();
const { data: existing, error: fetchError } = await supabase
.from('customer_claims')
.select('*')
.eq('id', claimId)
.eq('profile_id', companyId)
.single();
if (fetchError || !existing) {
return NextResponse.json({ error: 'Claim not found' }, { status: 404 });
}
const fields = [
'status',
'priority',
'title',
'description',
'amount_claimed',
'amount_approved',
'resolution_notes',
'owner_name',
'claim_type',
] as const;
const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };
for (const f of fields) {
if (body[f] !== undefined) updates[f] = body[f];
}
if (['resolved', 'closed', 'approved', 'rejected'].includes(String(body.status))) {
updates.resolved_at = new Date().toISOString();
}
const { data, error } = await supabase
.from('customer_claims')
.update(updates)
.eq('id', claimId)
.eq('profile_id', companyId)
.select('*')
.single();
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
return NextResponse.json({ success: true, claim: data });
} catch (e: unknown) {
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
}
}
@@ -0,0 +1,47 @@
// Provenance: bigfivefoods/supplieradvisor-mvp (vuln).
// repo: bigfivefoods/supplieradvisor-mvp
// commit: a7a9bc260d649ea2e582c07435bfd7d93100647b
// parent: a7a9bc260d649ea2e582c07435bfd7d93100647b
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8
// cve:
// license: MIT
// function: PATCH
// relpath: app/api/customers/claims/route.ts
// provenance: agent
// mechanism: identity_from_request_body
export async function PATCH(request: NextRequest) {
try {
const body = await request.json();
if (!body.id) return NextResponse.json({ error: 'id required' }, { status: 400 });
const fields = [
'status',
'priority',
'title',
'description',
'amount_claimed',
'amount_approved',
'resolution_notes',
'owner_name',
'claim_type',
] as const;
const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };
for (const f of fields) {
if (body[f] !== undefined) updates[f] = body[f];
}
if (['resolved', 'closed', 'approved', 'rejected'].includes(String(body.status))) {
updates.resolved_at = new Date().toISOString();
}
const supabase = getSupabaseServer();
const { data, error } = await supabase
.from('customer_claims')
.update(updates)
.eq('id', Number(body.id))
.select('*')
.single();
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
return NextResponse.json({ success: true, claim: data });
} catch (e: unknown) {
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
}
}
@@ -0,0 +1,157 @@
// Provenance: bigfivefoods/supplieradvisor-mvp (fixed).
// repo: bigfivefoods/supplieradvisor-mvp
// commit: a69e8f27c0f4d402573d16f0612b51155bbc46e1
// parent: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1
// cve:
// license: MIT
// function: GET
// relpath: app/api/customers/opportunities/route.ts
// provenance: agent
// mechanism: identity_from_request_body
export async function GET(request: NextRequest) {
try {
const companyId = Number(request.nextUrl.searchParams.get('companyId'));
const stage = request.nextUrl.searchParams.get('stage');
const q = (request.nextUrl.searchParams.get('q') || '').trim().toLowerCase();
if (!Number.isFinite(companyId) || companyId <= 0) {
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
}
const _gate = await requireCompanyAccess(request, companyId, { legacyPrivyUserId: legacyPrivyFrom(request) });
if (!_gate.ok) return _gate.response;
const supabase = getSupabaseServer();
const { loadHoldingSubtree, annotateGroupOpportunity } = await import(
'@/lib/business/holding-pipeline'
);
const tree = await loadHoldingSubtree(companyId);
let query = supabase
.from('opportunities')
.select('*')
.in('profile_id', tree.ids)
.order('updated_at', { ascending: false })
.limit(2000);
if (stage && stage !== 'all') {
query = query.or(`stage.eq.${stage},status.eq.${stage}`);
}
const { data, error } = await query;
if (error) {
return NextResponse.json({
success: true,
opportunities: [],
warning: error.message,
hint: 'Run 20260709_crm_leads_opportunities.sql',
});
}
let opportunities: OpportunityListItem[] = (data || []).map((raw) => {
const o = raw as Record<string, unknown>;
const st = normalizeStage(
o.stage as string | null,
o.status as string | null
);
const amount = Number(o.amount ?? o.opportunity_size ?? 0);
const probability =
o.probability != null ? Number(o.probability) : stageProbability(st);
const openDate =
toDateOnly(o.open_date as string | null) ||
toDateOnly(o.created_at as string | null) ||
null;
const expectedClose =
toDateOnly(o.expected_close_date as string | null) ||
toDateOnly(o.estimated_date as string | null) ||
null;
const actualClose = toDateOnly(o.actual_close_date as string | null);
const annotated = annotateGroupOpportunity(
{ ...o, stage: st, amount, probability },
companyId,
tree.names
);
return {
...o,
...annotated,
name: o.name ?? null,
contact_name: o.contact_name ?? null,
company_name: o.company_name ?? null,
contact_email: o.contact_email ?? null,
product_interest: o.product_interest ?? null,
stage: st,
amount,
probability,
open_date: openDate,
expected_close_date: expectedClose,
actual_close_date: actualClose,
contact_phone: o.contact_phone || o.contact_number || null,
location: o.location || o.opportunity_location || null,
description: o.description || o.notes || null,
weighted_amount: Math.round((amount * probability) / 100),
days_to_expected:
openDate && expectedClose
? Math.round(
(new Date(expectedClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
days_to_close:
openDate && actualClose
? Math.round(
(new Date(actualClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
days_open:
openDate && !actualClose
? Math.round(
(Date.now() - new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: openDate && actualClose
? Math.round(
(new Date(actualClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
};
});
if (q) {
opportunities = opportunities.filter((o) => {
const hay = [
searchHay(o.name),
searchHay(o.contact_name),
searchHay(o.company_name),
searchHay(o.contact_email),
searchHay(o.contact_phone),
searchHay(o.stage),
searchHay(o.product_interest),
]
.join(' ')
.toLowerCase();
return hay.includes(q);
});
}
const { summarizeGroupPipeline } = await import(
'@/lib/business/group-pipeline-view'
);
const group = summarizeGroupPipeline({
viewerCompanyId: companyId,
names: tree.names,
companyIds: tree.ids,
isSubsidiary: tree.isSubsidiary,
opportunities,
});
return NextResponse.json({
success: true,
opportunities,
group,
});
} catch (e: unknown) {
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
}
}
@@ -0,0 +1,155 @@
// Provenance: bigfivefoods/supplieradvisor-mvp (vuln).
// repo: bigfivefoods/supplieradvisor-mvp
// commit: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
// parent: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1
// cve:
// license: MIT
// function: GET
// relpath: app/api/customers/opportunities/route.ts
// provenance: agent
// mechanism: identity_from_request_body
export async function GET(request: NextRequest) {
try {
const companyId = Number(request.nextUrl.searchParams.get('companyId'));
const stage = request.nextUrl.searchParams.get('stage');
const q = (request.nextUrl.searchParams.get('q') || '').trim().toLowerCase();
if (!Number.isFinite(companyId)) {
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
}
const supabase = getSupabaseServer();
const { loadHoldingSubtree, annotateGroupOpportunity } = await import(
'@/lib/business/holding-pipeline'
);
const tree = await loadHoldingSubtree(companyId);
let query = supabase
.from('opportunities')
.select('*')
.in('profile_id', tree.ids)
.order('updated_at', { ascending: false })
.limit(2000);
if (stage && stage !== 'all') {
query = query.or(`stage.eq.${stage},status.eq.${stage}`);
}
const { data, error } = await query;
if (error) {
return NextResponse.json({
success: true,
opportunities: [],
warning: error.message,
hint: 'Run 20260709_crm_leads_opportunities.sql',
});
}
let opportunities: OpportunityListItem[] = (data || []).map((raw) => {
const o = raw as Record<string, unknown>;
const st = normalizeStage(
o.stage as string | null,
o.status as string | null
);
const amount = Number(o.amount ?? o.opportunity_size ?? 0);
const probability =
o.probability != null ? Number(o.probability) : stageProbability(st);
const openDate =
toDateOnly(o.open_date as string | null) ||
toDateOnly(o.created_at as string | null) ||
null;
const expectedClose =
toDateOnly(o.expected_close_date as string | null) ||
toDateOnly(o.estimated_date as string | null) ||
null;
const actualClose = toDateOnly(o.actual_close_date as string | null);
const annotated = annotateGroupOpportunity(
{ ...o, stage: st, amount, probability },
companyId,
tree.names
);
return {
...o,
...annotated,
name: o.name ?? null,
contact_name: o.contact_name ?? null,
company_name: o.company_name ?? null,
contact_email: o.contact_email ?? null,
product_interest: o.product_interest ?? null,
stage: st,
amount,
probability,
open_date: openDate,
expected_close_date: expectedClose,
actual_close_date: actualClose,
contact_phone: o.contact_phone || o.contact_number || null,
location: o.location || o.opportunity_location || null,
description: o.description || o.notes || null,
weighted_amount: Math.round((amount * probability) / 100),
days_to_expected:
openDate && expectedClose
? Math.round(
(new Date(expectedClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
days_to_close:
openDate && actualClose
? Math.round(
(new Date(actualClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
days_open:
openDate && !actualClose
? Math.round(
(Date.now() - new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: openDate && actualClose
? Math.round(
(new Date(actualClose).getTime() -
new Date(openDate).getTime()) /
(24 * 60 * 60 * 1000)
)
: null,
};
});
if (q) {
opportunities = opportunities.filter((o) => {
const hay = [
searchHay(o.name),
searchHay(o.contact_name),
searchHay(o.company_name),
searchHay(o.contact_email),
searchHay(o.contact_phone),
searchHay(o.stage),
searchHay(o.product_interest),
]
.join(' ')
.toLowerCase();
return hay.includes(q);
});
}
const { summarizeGroupPipeline } = await import(
'@/lib/business/group-pipeline-view'
);
const group = summarizeGroupPipeline({
viewerCompanyId: companyId,
names: tree.names,
companyIds: tree.ids,
isSubsidiary: tree.isSubsidiary,
opportunities,
});
return NextResponse.json({
success: true,
opportunities,
group,
});
} catch (e: unknown) {
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
}
}
@@ -0,0 +1,61 @@
# Provenance: D-sorganization/Tools (fixed).
# repo: D-sorganization/Tools
# commit: a96bc0502a3dcdac303e4f0152508886e5c35c0a
# parent: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
# commit_url: https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a
# cve:
# license: MIT
# function: _is_command_allowed
# relpath: src/shared/python/ai/tools/cli_tools.py
# provenance: agent
# mechanism: source_reaches_sink
def _is_command_allowed(self, command: str) -> bool:
"""Check if a command is allowed.
Args:
command: Command to check.
Returns:
True if allowed, False otherwise.
"""
# Dangerous commands are never allowed
dangerous = ["rm", "sudo", "chmod", "chown", "curl", "wget", "ssh"]
# Prevent shell injection by blocking command separators/operators
shell_operators = ["&&", "||", ";", "|", ">", "<", "$", "`", "\n", "&"]
if any(op in command for op in shell_operators):
return False
try:
tokens = shlex.split(command)
if not tokens:
return False
# Verify the first token is in the allowlist
base_cmd = tokens[0]
if base_cmd not in self._allowed_commands:
return False
# Verify no token is a dangerous command
for token in tokens:
if token in dangerous:
return False
try:
# Check for absolute/relative paths (e.g., /bin/rm, ./rm)
if Path(token).name in dangerous:
return False
# Check for assignments passing executables (e.g., --exec=/bin/rm)
if "=" in token:
val = token.split("=", 1)[1]
if val in dangerous or Path(val).name in dangerous:
return False
except Exception:
pass
return True
except ValueError:
# e.g., missing closing quote
return False
@@ -0,0 +1,48 @@
# Provenance: D-sorganization/Tools (vuln).
# repo: D-sorganization/Tools
# commit: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
# parent: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
# commit_url: https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a
# cve:
# license: MIT
# function: _is_command_allowed
# relpath: src/shared/python/ai/tools/cli_tools.py
# provenance: agent
# mechanism: source_reaches_sink
def _is_command_allowed(self, command: str) -> bool:
"""Check if a command is allowed.
Args:
command: Command to check.
Returns:
True if allowed, False otherwise.
"""
# Dangerous commands are never allowed
dangerous = ["rm", "sudo", "chmod", "chown", "curl", "wget", "ssh"]
# Prevent shell injection by blocking command separators/operators
shell_operators = ["&&", "||", ";", "|", ">", "<", "$", "`", "\n", "&"]
if any(op in command for op in shell_operators):
return False
try:
tokens = shlex.split(command)
if not tokens:
return False
# Verify the first token is in the allowlist
base_cmd = tokens[0]
if base_cmd not in self._allowed_commands:
return False
# Verify no token is a dangerous command
for token in tokens:
if token in dangerous:
return False
return True
except ValueError:
# e.g., missing closing quote
return False
@@ -0,0 +1,48 @@
// Provenance: trackly-app/trackly-cli (fixed).
// repo: trackly-app/trackly-cli
// commit: 1c1aed89b07edb04051830c8f086e02b65e961c6
// parent: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
// commit_url: https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6
// cve:
// license: MIT
// function: inspectExistingAncestor
// relpath: lib/path-diagnostics.js
// provenance: agent
// mechanism: path_join_user_input
async function inspectExistingAncestor(exactPath, stat = fs.stat) {
let candidate = exactPath;
while (true) {
try {
const stats = await stat(candidate);
return {
ancestor: candidate,
exactPathExists: candidate === exactPath,
exactPathType: candidate === exactPath ? (stats.isDirectory() ? 'directory' : 'file') : null,
writableDirectory: stats.isDirectory() ? candidate : path.dirname(candidate),
inspectionErrorCode: null,
};
} catch (error) {
if (error.code !== 'ENOENT') {
return {
ancestor: candidate,
exactPathExists: null,
exactPathType: null,
writableDirectory: null,
inspectionErrorCode: error.code || 'path_inspection_failed',
};
}
const parent = path.dirname(candidate);
if (parent === candidate) {
return {
ancestor: parent,
exactPathExists: false,
exactPathType: null,
writableDirectory: parent,
inspectionErrorCode: null,
};
}
candidate = parent;
}
}
}
@@ -0,0 +1,33 @@
// Provenance: trackly-app/trackly-cli (vuln).
// repo: trackly-app/trackly-cli
// commit: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
// parent: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
// commit_url: https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6
// cve:
// license: MIT
// function: inspectExistingAncestor
// relpath: lib/path-diagnostics.js
// provenance: agent
// mechanism: path_join_user_input
async function inspectExistingAncestor(exactPath) {
let candidate = exactPath;
while (true) {
try {
const stats = await fs.stat(candidate);
return {
ancestor: candidate,
exactPathExists: candidate === exactPath,
exactPathType: candidate === exactPath ? (stats.isDirectory() ? 'directory' : 'file') : null,
writableDirectory: stats.isDirectory() ? candidate : path.dirname(candidate),
};
} catch (error) {
if (error.code !== 'ENOENT') throw error;
const parent = path.dirname(candidate);
if (parent === candidate) {
return { ancestor: parent, exactPathExists: false, exactPathType: null, writableDirectory: parent };
}
candidate = parent;
}
}
}
@@ -0,0 +1,33 @@
# Provenance: D-sorganization/UpstreamDrift (fixed).
# repo: D-sorganization/UpstreamDrift
# commit: c3a0787080489b30e2ed0abfac03b51e45da184b
# parent: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
# commit_url: https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b
# cve:
# license: MIT
# function: _find_logo_file
# relpath: src/api/local_server.py
# provenance: agent
# mechanism: path_join_user_input
def _find_logo_file(logo_name: str) -> Path | None:
"""Search for a logo file in known asset directories.
The caller-supplied ``logo_name`` is joined onto each candidate root via
:func:`_safe_join` so that ``..`` traversal, absolute paths, and symlink
escape are rejected before touching the filesystem.
Args:
logo_name: Filename of the logo to find.
Returns:
Path to the logo file, or None if not found or rejected as unsafe.
"""
for root in (
Path(__file__).parent.parent.parent / "assets" / "logos",
Path(__file__).parent.parent / "launchers" / "assets",
):
resolved = _safe_join(root, logo_name)
if resolved is not None and resolved.exists() and resolved.is_file():
return resolved
return None
@@ -0,0 +1,30 @@
# Provenance: D-sorganization/UpstreamDrift (vuln).
# repo: D-sorganization/UpstreamDrift
# commit: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
# parent: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
# commit_url: https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b
# cve:
# license: MIT
# function: _find_logo_file
# relpath: src/api/local_server.py
# provenance: agent
# mechanism: path_join_user_input
def _find_logo_file(logo_name: str) -> Path | None:
"""Search for a logo file in known asset directories.
Args:
logo_name: Filename of the logo to find.
Returns:
Path to the logo file, or None if not found.
"""
logos_dir = Path(__file__).parent.parent.parent / "assets" / "logos"
logo_path = logos_dir / logo_name
if logo_path.exists() and logo_path.is_file():
return logo_path
launcher_logos = Path(__file__).parent.parent / "launchers" / "assets"
alt_path = launcher_logos / logo_name
if alt_path.exists() and alt_path.is_file():
return alt_path
return None
@@ -0,0 +1,28 @@
# Provenance: Ahkeratmehilaiset/waggledance-swarm (fixed).
# repo: Ahkeratmehilaiset/waggledance-swarm
# commit: 9a454843aa35332ff2eb3106023eee0c4b5e444b
# parent: 934b939f1cca5259eaf807db3319eb97b90d8d80
# commit_url: https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b
# cve:
# license: Apache-2.0
# function: normalize_allowed_hosts
# relpath: waggledance/core/v3_13_0/ssrf_host_guard.py
# provenance: agent
# mechanism: source_reaches_sink
def normalize_allowed_hosts(raw_hosts: Iterable[str]) -> frozenset[str]:
"""Validate and canonicalize an exact-host allowlist."""
if (
not isinstance(raw_hosts, Iterable)
or isinstance(raw_hosts, (str, bytes, Mapping))
):
raise ValueError("ALLOWLIST_HOSTS_REFUSED")
normalized: set[str] = set()
for index, host in enumerate(raw_hosts):
if not isinstance(host, str) or not host.strip():
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
clean = normalize_host(host)
if "://" in clean or "/" in clean or "?" in clean or "@" in clean:
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
normalized.add(clean)
return frozenset(normalized)
@@ -0,0 +1,25 @@
# Provenance: Ahkeratmehilaiset/waggledance-swarm (vuln).
# repo: Ahkeratmehilaiset/waggledance-swarm
# commit: 934b939f1cca5259eaf807db3319eb97b90d8d80
# parent: 934b939f1cca5259eaf807db3319eb97b90d8d80
# commit_url: https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b
# cve:
# license: Apache-2.0
# function: normalize_allowed_hosts
# relpath: waggledance/core/v3_13_0/ssrf_host_guard.py
# provenance: agent
# mechanism: source_reaches_sink
def normalize_allowed_hosts(raw_hosts: Sequence[str]) -> frozenset[str]:
"""Validate and canonicalize an exact-host allowlist."""
if not isinstance(raw_hosts, Sequence) or isinstance(raw_hosts, (str, bytes)):
raise ValueError("ALLOWLIST_HOSTS_REFUSED")
normalized: set[str] = set()
for index, host in enumerate(raw_hosts):
if not isinstance(host, str) or not host.strip():
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
clean = normalize_host(host)
if "://" in clean or "/" in clean or "?" in clean or "@" in clean:
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
normalized.add(clean)
return frozenset(normalized)
@@ -0,0 +1,162 @@
// Provenance: G4brym/workers-research (fixed).
// repo: G4brym/workers-research
// commit: 209444eb61cc564c2d6b43267256f85fe3e5e30e
// parent: eab923ad3099c01b002fbd6be7cf994614bbdee4
// commit_url: https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e
// cve:
// license: MIT
// function: formatDuration
// relpath: src/utils.ts
// provenance: agent
// mechanism: source_reaches_sink
import {
createGoogleGenerativeAI,
type GoogleGenerativeAIProvider,
type GoogleGenerativeAIProviderSettings,
} from "@ai-sdk/google";
import type { Env } from "./bindings";
function getGoogleProvider(env: Env): GoogleGenerativeAIProvider {
const args: GoogleGenerativeAIProviderSettings = {
apiKey: env.GOOGLE_API_KEY,
};
if (env.AI_GATEWAY_ACCOUNT_ID && env.AI_GATEWAY_NAME) {
args.baseURL = `https://gateway.ai.cloudflare.com/v1/${env.AI_GATEWAY_ACCOUNT_ID}/${env.AI_GATEWAY_NAME}/google-ai-studio/v1beta`;
if (env.AI_GATEWAY_API_KEY) {
args.headers = {
"cf-aig-authorization": `Bearer ${env.AI_GATEWAY_API_KEY}`,
};
}
}
return createGoogleGenerativeAI(args);
}
export function getModel(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash-exp");
}
export function getFallbackModel(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash");
}
export function getModelThinking(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash-exp");
}
export function timeAgo(date: Date): string {
const now = new Date();
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
const intervals: [number, string][] = [
[60, "minute"],
[60, "hour"],
[24, "day"],
[7, "week"],
[4.35, "month"],
[12, "year"],
];
let count = seconds;
let unit = "second";
for (const [interval, name] of intervals) {
if (count < interval) break;
count /= interval;
unit = name;
}
count = Math.floor(count);
return `${count} ${unit}${count !== 1 ? "s" : ""} ago`;
}
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Normalize a domain input for excluded domain matching.
* Handles common user input formats:
* - Full URLs: "https://reddit.com/foo" → "reddit.com"
* - www prefix: "www.reddit.com" → "reddit.com"
* - Mixed: "https://www.reddit.com" → "reddit.com"
* - Plain domains are returned as-is (lowercased, trimmed)
*/
export function normalizeDomain(input: string): string {
let domain = input.trim().toLowerCase();
if (domain.length === 0) return "";
// If it looks like a URL (has ://), extract the hostname
if (domain.includes("://")) {
try {
domain = new URL(domain).hostname;
} catch {
// If URL parsing fails, strip the protocol manually
domain = domain.replace(/^[a-z]+:\/\//, "").split("/")[0];
}
} else {
// Strip any trailing path from plain domain input
domain = domain.split("/")[0];
}
// Strip www. prefix for consistent matching
domain = domain.replace(/^www\./, "");
return domain;
}
/**
* Build parameterized search filter conditions for research list queries.
* Uses parameterized queries to prevent SQL injection.
*/
export function buildSearchFilters(
q?: string,
status?: string,
): { conditions: string[]; params: (string | number)[] } {
const conditions: string[] = [];
const params: (string | number)[] = [];
if (q?.trim()) {
const searchTerm = `%${q.trim()}%`;
conditions.push("(title LIKE ? OR query LIKE ?)");
params.push(searchTerm, searchTerm);
}
if (status && ["1", "2", "3"].includes(status)) {
conditions.push("status = ?");
params.push(Number.parseInt(status, 10));
}
return { conditions, params };
}
export function formatDuration(ms: number): string {
// Handle negative or zero values
if (ms <= 0) {
return "0.0 seconds";
}
const seconds = ms / 1000;
const minutes = seconds / 60;
const hours = minutes / 60;
const days = hours / 24;
// Determine the appropriate unit and format with one decimal place
if (days >= 1) {
return `${days.toFixed(1)} day${days !== 1 ? "s" : ""}`;
} else if (hours >= 1) {
return `${hours.toFixed(1)} hour${hours !== 1 ? "s" : ""}`;
} else if (minutes >= 1) {
return `${minutes.toFixed(1)} minute${minutes !== 1 ? "s" : ""}`;
} else {
return `${seconds.toFixed(1)} second${seconds !== 1 ? "s" : ""}`;
}
}
@@ -0,0 +1,137 @@
// Provenance: G4brym/workers-research (vuln).
// repo: G4brym/workers-research
// commit: eab923ad3099c01b002fbd6be7cf994614bbdee4
// parent: eab923ad3099c01b002fbd6be7cf994614bbdee4
// commit_url: https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e
// cve:
// license: MIT
// function: formatDuration
// relpath: src/utils.ts
// provenance: agent
// mechanism: source_reaches_sink
import {
createGoogleGenerativeAI,
type GoogleGenerativeAIProvider,
type GoogleGenerativeAIProviderSettings,
} from "@ai-sdk/google";
import type { Env } from "./bindings";
function getGoogleProvider(env: Env): GoogleGenerativeAIProvider {
const args: GoogleGenerativeAIProviderSettings = {
apiKey: env.GOOGLE_API_KEY,
};
if (env.AI_GATEWAY_ACCOUNT_ID && env.AI_GATEWAY_NAME) {
args.baseURL = `https://gateway.ai.cloudflare.com/v1/${env.AI_GATEWAY_ACCOUNT_ID}/${env.AI_GATEWAY_NAME}/google-ai-studio/v1beta`;
if (env.AI_GATEWAY_API_KEY) {
args.headers = {
"cf-aig-authorization": `Bearer ${env.AI_GATEWAY_API_KEY}`,
};
}
}
return createGoogleGenerativeAI(args);
}
export function getModel(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash-exp");
}
export function getFallbackModel(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash");
}
export function getModelThinking(env: Env) {
const google = getGoogleProvider(env);
return google("gemini-2.0-flash-exp");
}
export function timeAgo(date: Date): string {
const now = new Date();
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
const intervals: [number, string][] = [
[60, "minute"],
[60, "hour"],
[24, "day"],
[7, "week"],
[4.35, "month"],
[12, "year"],
];
let count = seconds;
let unit = "second";
for (const [interval, name] of intervals) {
if (count < interval) break;
count /= interval;
unit = name;
}
count = Math.floor(count);
return `${count} ${unit}${count !== 1 ? "s" : ""} ago`;
}
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Normalize a domain input for excluded domain matching.
* Handles common user input formats:
* - Full URLs: "https://reddit.com/foo" → "reddit.com"
* - www prefix: "www.reddit.com" → "reddit.com"
* - Mixed: "https://www.reddit.com" → "reddit.com"
* - Plain domains are returned as-is (lowercased, trimmed)
*/
export function normalizeDomain(input: string): string {
let domain = input.trim().toLowerCase();
if (domain.length === 0) return "";
// If it looks like a URL (has ://), extract the hostname
if (domain.includes("://")) {
try {
domain = new URL(domain).hostname;
} catch {
// If URL parsing fails, strip the protocol manually
domain = domain.replace(/^[a-z]+:\/\//, "").split("/")[0];
}
} else {
// Strip any trailing path from plain domain input
domain = domain.split("/")[0];
}
// Strip www. prefix for consistent matching
domain = domain.replace(/^www\./, "");
return domain;
}
export function formatDuration(ms: number): string {
// Handle negative or zero values
if (ms <= 0) {
return "0.0 seconds";
}
const seconds = ms / 1000;
const minutes = seconds / 60;
const hours = minutes / 60;
const days = hours / 24;
// Determine the appropriate unit and format with one decimal place
if (days >= 1) {
return `${days.toFixed(1)} day${days !== 1 ? "s" : ""}`;
} else if (hours >= 1) {
return `${hours.toFixed(1)} hour${hours !== 1 ? "s" : ""}`;
} else if (minutes >= 1) {
return `${minutes.toFixed(1)} minute${minutes !== 1 ? "s" : ""}`;
} else {
return `${seconds.toFixed(1)} second${seconds !== 1 ? "s" : ""}`;
}
}
@@ -0,0 +1,19 @@
// Provenance: zoonk/zoonk (fixed).
// repo: zoonk/zoonk
// commit: bfbf670ccb41d63c407d32c51bd26e626a174f31
// parent: 2604269350bff51f58572c133b45010cb0976a5a
// commit_url: https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31
// cve:
// license: MIT
// function: getAllowedHosts
// relpath: packages/utils/src/origin.ts
// provenance: agent
// mechanism: permissive_default
export function getAllowedHosts(): string[] {
return [
...ZOONK_DOMAINS.flatMap((domain) => [domain, `*.${domain}`]),
...(isLocalhostSupported() ? ["localhost:*"] : []),
...(canAcceptVercelPreviewOrigins() ? [ZOONK_VERCEL_PREVIEW_HOST] : []),
];
}
@@ -0,0 +1,19 @@
// Provenance: zoonk/zoonk (vuln).
// repo: zoonk/zoonk
// commit: 2604269350bff51f58572c133b45010cb0976a5a
// parent: 2604269350bff51f58572c133b45010cb0976a5a
// commit_url: https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31
// cve:
// license: MIT
// function: getAllowedHosts
// relpath: packages/utils/src/origin.ts
// provenance: agent
// mechanism: permissive_default
export function getAllowedHosts(): string[] {
return [
...ZOONK_DOMAINS.flatMap((domain) => [domain, `*.${domain}`]),
...(isLocalhostSupported() ? ["localhost:*"] : []),
...(getEnvironment() === "production" ? [] : ["*-zoonk.vercel.app"]),
];
}
+60
View File
@@ -151,3 +151,63 @@ url = "https://github.com/curl/curl"
level = "commit/function"
languages = ["C"]
notes = "Public git. Seed: CVE-2023-38545 do_SOCKS5. Isolated functions only; do not vendor the tree."
# --- pair-corpus-honesty: web, agent-authored, and LLM-generated corpora ---
[[dataset]]
name = "Real-Vuln-Benchmark"
url = "https://github.com/kolega-ai/Real-Vuln-Benchmark"
data = "benchmarks/pairs/vibe-py"
level = "repo/function/line"
languages = ["Python"]
notes = "Apache-2.0 (v2). 66 pinned Python web repos: 26 human-authored, 40 LLM-generated (Claude, GPT, Kimi) seeded with reviewed vulns. 1896 vulnerable findings + 280 false-positive traps with file, line range, function, primary/acceptable CWEs, severity, authorship. Educational/CTF style, not production. Source of the `vibe-py` slice; traps are the fixed-side twins."
[[dataset]]
name = "SecBench.js"
url = "https://github.com/cristianstaicu/SecBench.js"
level = "package/sink-line"
languages = ["JavaScript"]
notes = "600 real npm vulnerabilities (prototype pollution, ReDoS, command injection, path traversal, code injection) with Jest exploit oracles, fixCommit, fixedVersion, and sinkLocation. No license file: never vendor its test files; harvest function pairs from the upstream package repositories named in fixCommit (`vfc-js` slice) and record each package's own license."
[[dataset]]
name = "AIDev"
url = "https://huggingface.co/datasets/hao-li/AIDev"
level = "pull request"
languages = ["multi"]
notes = "932k agent-authored PRs (Claude Code, Codex, Copilot, Cursor, Devin, Jules) with patches and language; CC-BY-4.0 index, source repos keep their licenses. No security labels. Candidate source for `agent-vfc` together with GitHub commit search on agent co-author trailers."
[[dataset]]
name = "BaxBench"
url = "https://github.com/logic-star-ai/baxbench"
data = "https://huggingface.co/datasets/LogicStar/BaxBench"
level = "scenario/exploit"
languages = ["Python", "JavaScript", "TypeScript", "Go", "Rust", "PHP"]
notes = "MIT. 28 backend scenarios x 14 frameworks (Express, Flask, FastAPI, Django, Nest, ...) with functional tests and executable exploits per CWE. Generated code is not shipped; generate with any model, the exploit harness labels each sample. Deferred slice (`baxgen`) until deep mode can run its exploits."
[[dataset]]
name = "SecurityEval"
url = "https://github.com/s2e-lab/SecurityEval"
level = "prompt/sample"
languages = ["Python"]
notes = "121 prompts over 69 CWEs with Copilot and InCoder outputs. Vibe-textbook only; not web recall."
[[dataset]]
name = "CodeSecEval"
url = "https://arxiv.org/abs/2407.02395"
level = "sample"
languages = ["Python"]
notes = "180 samples, 44 vulnerability types, insecure and secure executable code with tests. Pointer only."
[[dataset]]
name = "CWEval"
url = "https://github.com/Co1lin/CWEval"
level = "task"
languages = ["C", "Python", "JavaScript"]
notes = "Functionality plus security evaluation of LLM-generated code on the same tasks. Pointer only."
[[dataset]]
name = "CyberSecEval insecure code"
url = "https://github.com/meta-llama/PurpleLlama/tree/main/CybersecurityBenchmarks"
level = "test case"
languages = ["C", "C++", "C#", "Java", "JavaScript", "PHP", "Python", "Rust"]
notes = "MIT. Labels are DEFINED by its Insecure Code Detector regex/semgrep/weggli rules. Circular for a rule-proposing tool: coverage pointer only, never recall ground truth."
+83
View File
@@ -0,0 +1,83 @@
# Closed mechanism vocabulary for pair labels (pair-corpus-honesty, Req 2.1).
# Every [[pair.expected]] row names one of these ids. Bump `version` when the set changes.
version = "1"
[[mechanism]]
id = "source_reaches_sink"
definition = "A fact-listed source flows by name into a fact-listed sink without a sanitizer."
[[mechanism]]
id = "container_taint"
definition = "Taint travels through a mutable container or config object (list.append, dict[key], ConfigParser.set/get) before the sink."
[[mechanism]]
id = "config_sink_weak_literal"
definition = "A configuration sink is dangerous because of a literal argument (hashlib.new('md5'), MessageDigest 'SHA-1', debug=True)."
[[mechanism]]
id = "unchecked_length_copy"
definition = "A copy or read uses a length or index that is not bounded by a dominating check."
[[mechanism]]
id = "unchecked_alloc_size"
definition = "An allocation size derives from untrusted or unbounded input."
[[mechanism]]
id = "null_deref_unguarded"
definition = "A pointer that may be NULL is dereferenced without a dominating NULL test."
[[mechanism]]
id = "signed_size_operand"
definition = "A signed or narrower type feeds a size or length operand and can wrap."
[[mechanism]]
id = "fixed_buffer_capacity"
definition = "A fixed-size buffer receives data larger than its declared capacity."
[[mechanism]]
id = "identity_from_request_body"
definition = "A user or owner identity is taken from the request body or query instead of the authenticated context."
[[mechanism]]
id = "missing_auth_guard"
definition = "A route or handler performs a privileged action with no authentication or authorization guard on its path."
[[mechanism]]
id = "secret_in_client"
definition = "A secret or privileged key is shipped to client-side code or committed configuration."
[[mechanism]]
id = "permissive_default"
definition = "A security control is left at a permissive default (RLS off, CORS wildcard, debug mode, open bucket)."
[[mechanism]]
id = "path_join_user_input"
definition = "A filesystem path is built from user input without normalization or containment."
[[mechanism]]
id = "prototype_pollution"
definition = "Attacker-controlled keys reach a recursive merge or assignment that writes Object.prototype."
[[mechanism]]
id = "redos"
definition = "A regular expression with catastrophic backtracking is applied to untrusted input."
[[mechanism]]
id = "uaf"
definition = "Memory is used after it was released."
[[mechanism]]
id = "type_confusion"
definition = "A value is interpreted as a type it is not."
[[mechanism]]
id = "validation_strength"
definition = "A validator exists but accepts inputs it should reject; the fix strengthens the check."
[[mechanism]]
id = "cross_artifact"
definition = "The bug is only decidable with an artifact outside the vendored files (a properties file, a schema, a build flag)."
[[mechanism]]
id = "other"
definition = "Not yet classified. Present so bulk-mined pairs load; review should replace it."
+14
View File
@@ -0,0 +1,14 @@
# vfc-js slice
Server-side JavaScript function pairs harvested from the **upstream fix commits** that
[SecBench.js](https://github.com/cristianstaicu/SecBench.js) records in its package metadata
(`fixCommit`, `sink`). SecBench.js itself has no license file, so none of its files are vendored;
each excerpt carries the upstream package's license.
- Classes: command injection, path traversal, code injection first. Prototype pollution and ReDoS
rows may be added with their own mechanism and `known_limit` until the engine can talk about them.
- Mode: `hunk` (the function enclosing the first changed hunk on each side).
- Provenance: `human`.
Rebuild: `python benchmarks/pairs/vfc-js/build_recipes.py --crawl /tmp/secbench.jsonl` then
`--from /tmp/secbench.jsonl`, `harvest.py --slice vfc-js --all --fetch`, `catalog_gen.py --slice vfc-js`.
@@ -0,0 +1,55 @@
// Provenance: simonh1000/angular-http-server (fixed).
// repo: simonh1000/angular-http-server
// commit: 8bafc9577161469f5dea01e0b98ea9c525d063e9
// parent: d171a771a92e4685b24fb77cb894a7b7b8024c5c
// commit_url: https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9
// cve:
// license: Apache-2.0
// function: requestListener
// relpath: angular-http-server.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 45
function requestListener(req, res) {
// Add CORS header if option chosen
if (argv.cors) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', 'authorization, content-type');
// When the request is for CORS OPTIONS (rather than a page) return just the headers
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
}
// Request is for a page instead
// Only interested in the part before any query params
var url = req.url.split('?')[0]
// Attaches path prefix with --path option
var possibleFilename = resolveUrl(url.slice(1)) || "dummy";
var safeFileName = path.normalize(possibleFilename).replace(/^(\.\.[\/\\])+/, '');
var safeFullFilename = path.join(__dirname, safeFileName);
fs.stat(safeFullFilename, function(err, stats) {
var fileBuffer;
if (!err && stats.isFile()) {
fileBuffer = fs.readFileSync(safeFullFilename);
let ct = mime.lookup(safeFullFilename);
log(`Sending ${safeFullFilename} with Content-Type ${ct}`);
res.writeHead(200, { 'Content-Type': ct });
} else {
log("Route %s, replacing with index.html", safeFullFilename);
fileBuffer = returnDistFile();
res.writeHead(200, { 'Content-Type': 'text/html' });
}
res.write(fileBuffer);
res.end();
});
}
@@ -0,0 +1,52 @@
// Provenance: simonh1000/angular-http-server (vuln).
// repo: simonh1000/angular-http-server
// commit: d171a771a92e4685b24fb77cb894a7b7b8024c5c
// parent: d171a771a92e4685b24fb77cb894a7b7b8024c5c
// commit_url: https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9
// cve:
// license: Apache-2.0
// function: requestListener
// relpath: angular-http-server.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 45
function requestListener(req, res) {
// Add CORS header if option chosen
if (argv.cors) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', 'authorization, content-type');
// When the request is for CORS OPTIONS (rather than a page) return just the headers
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
}
// Request is for a page instead
// Only interested in the part before any query params
var url = req.url.split('?')[0]
// Attaches path prefix with --path option
var possibleFilename = resolveUrl(url.slice(1)) || "dummy";
fs.stat(possibleFilename, function(err, stats) {
var fileBuffer;
if (!err && stats.isFile()) {
fileBuffer = fs.readFileSync(possibleFilename);
let ct = mime.lookup(possibleFilename);
log(`Sending ${possibleFilename} with Content-Type ${ct}`);
res.writeHead(200, { 'Content-Type': ct });
} else {
log("Route %s, replacing with index.html", possibleFilename);
fileBuffer = returnDistFile();
res.writeHead(200, { 'Content-Type': 'text/html' });
}
res.write(fileBuffer);
res.end();
});
}
@@ -0,0 +1,95 @@
// Provenance: vincentmorneau/apex-publish-static-files (fixed).
// repo: vincentmorneau/apex-publish-static-files
// commit: 2209af8f2b65c24aa55ab757e0e05b958c16f063
// parent: 8d28fe8a9a49e5ff3f61e239293b5646528e2915
// commit_url: https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063
// cve: CVE-2018-16462
// license: MIT
// function: publish
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 7
module.exports = {
// Validates a JSON object
publish(opts) {
// Set defaults
const defaults = {
sqlclPath: 'sql',
destination: 'application'
};
opts = Object.assign(defaults, opts);
// Validate arguments
if (typeof opts.connectString === 'undefined') {
throw new TypeError('connectString is required.');
}
if (typeof opts.directory === 'undefined') {
throw new TypeError('directory is a required argument.');
}
if (typeof opts.appID === 'undefined') {
throw new TypeError('appID is a required argument.');
}
if (opts.destination.toLowerCase() === 'plugin' && typeof opts.pluginName === 'undefined') {
throw new Error('pluginName is a required argument.');
}
if (!fs.existsSync(opts.directory)) {
throw new Error(`Directory ${opts.directory} is not a valid path.`);
}
const getAllFiles = dir =>
fs.readdirSync(dir).reduce((files, file) => {
const name = path.join(dir, file);
const isDirectory = fs.statSync(name).isDirectory();
return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
}, []);
if (getAllFiles(opts.directory).length === 0) {
console.log(`Directory is empty.`);
} else {
// Execute the upload process
try {
switch (opts.destination.toLowerCase()) {
case 'theme':
console.log(`Uploading to ${opts.appID} - Theme Files...`);
break;
case 'workspace':
console.log(`Uploading to ${opts.appID} - Workspace Files...`);
break;
case 'plugin':
console.log(`Uploading to ${opts.appID} - ${opts.pluginName} - Plugin Files...`);
break;
default:
console.log(`Uploading to ${opts.appID} - Application Static Files...`);
}
const spawnOpts = [
opts.connectString, // Connect string (user/pass@server:port/sid)
'@' + path.resolve(__dirname, 'lib/script'), // Sql to execute
path.resolve(__dirname, 'lib/distUpload.js'), // Param &1 (js to execute)
path.resolve(opts.directory), // Param &2
opts.appID, // Param &3
opts.destination, // Param &4
opts.pluginName // Param &5
];
const childProcess = spawnSync(
opts.sqlclPath, // Sqlcl path
spawnOpts, {
encoding: 'utf8'
}
);
console.log(childProcess.stdout);
console.log('Files were uploaded successfully.');
} catch (err) {
console.error(err);
}
}
}
};
@@ -0,0 +1,85 @@
// Provenance: vincentmorneau/apex-publish-static-files (vuln).
// repo: vincentmorneau/apex-publish-static-files
// commit: 8d28fe8a9a49e5ff3f61e239293b5646528e2915
// parent: 8d28fe8a9a49e5ff3f61e239293b5646528e2915
// commit_url: https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063
// cve: CVE-2018-16462
// license: MIT
// function: publish
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 7
module.exports = {
// Validates a JSON object
publish(opts) {
// Set defaults
const defaults = {
sqlclPath: 'sql',
destination: 'application'
};
opts = Object.assign(defaults, opts);
// Validate arguments
if (typeof opts.connectString === 'undefined') {
throw new TypeError('connectString is required.');
}
if (typeof opts.directory === 'undefined') {
throw new TypeError('directory is a required argument.');
}
if (typeof opts.appID === 'undefined') {
throw new TypeError('appID is a required argument.');
}
if (opts.destination.toLowerCase() === 'plugin' && typeof opts.pluginName === 'undefined') {
throw new Error('pluginName is a required argument.');
}
if (!fs.existsSync(opts.directory)) {
throw new Error(`Directory ${opts.directory} is not a valid path.`);
}
// Execute the upload process
try {
switch (opts.destination.toLowerCase()) {
case 'theme':
console.log(`Uploading to ${opts.appID} - Theme Files...`);
break;
case 'workspace':
console.log(`Uploading to ${opts.appID} - Workspace Files...`);
break;
case 'plugin':
console.log(`Uploading to ${opts.appID} - ${opts.pluginName} - Plugin Files...`);
break;
default:
console.log(`Uploading to ${opts.appID} - Application Static Files...`);
}
const childProcess = execSync(
'"' + opts.sqlclPath + '"' + // Sqlcl path
' ' + opts.connectString + // Connect string (user/pass@server:port/sid)
' @"' + path.resolve(__dirname, 'lib/script') + '"' + // Sql to execute
' "' + path.resolve(__dirname, 'lib/distUpload.js') + '"' + // Param &1 (js to execute)
' "' + path.resolve(opts.directory) + '"' + // Param &2
' ' + opts.appID + // Param &3
' "' + opts.destination + '"' + // Param &4
' "' + opts.pluginName + '"' // Param &5
, {
encoding: 'utf8'
}
);
console.log(childProcess);
console.log('Files were uploaded successfully.');
return true;
} catch (err) {
console.error(err);
return false;
}
}
};
@@ -0,0 +1,43 @@
// Provenance: nfriedly/node-bestzip (fixed).
// repo: nfriedly/node-bestzip
// commit: 45d4a901478c6a8f396c8b959dd6cf8fd3f955b6
// parent: fcea252e52b6078eff6caf5531bd32c53fccb59f
// commit_url: https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6
// cve: CVE-2020-7730
// license: MIT
// function: nativeZip
// relpath: lib/bestzip.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 66
const nativeZip = options =>
new Promise((resolve, reject) => {
const cwd = options.cwd || process.cwd();
const command = "zip";
expandSources(cwd, options.source, (err, sources) => {
const args = ["--quiet", "--recurse-paths", options.destination].concat(
sources
);
const zipProcess = cp.spawn(command, args, {
stdio: "inherit",
cwd
});
zipProcess.on("error", reject);
zipProcess.on("close", exitCode => {
if (exitCode === 0) {
resolve();
} else {
// exit code 12 means "nothing to do" right?
//console.log('rejecting', zipProcess)
reject(
new Error(
`Unexpected exit code from native zip: ${exitCode}\n executed command '${command} ${args.join(
" "
)}'\n executed in directory '${cwd}'`
)
);
}
});
});
});
@@ -0,0 +1,41 @@
// Provenance: nfriedly/node-bestzip (vuln).
// repo: nfriedly/node-bestzip
// commit: fcea252e52b6078eff6caf5531bd32c53fccb59f
// parent: fcea252e52b6078eff6caf5531bd32c53fccb59f
// commit_url: https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6
// cve: CVE-2020-7730
// license: MIT
// function: nativeZip
// relpath: lib/bestzip.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 66
const nativeZip = options =>
new Promise((resolve, reject) => {
const sources = Array.isArray(options.source)
? options.source.join(" ")
: options.source;
const command = `zip --quiet --recurse-paths ${
options.destination
} ${sources}`;
const zipProcess = cp.exec(command, {
stdio: "inherit",
cwd: options.cwd
});
zipProcess.on("error", reject);
zipProcess.on("close", exitCode => {
if (exitCode === 0) {
resolve();
} else {
// exit code 12 means "nothing to do" right?
//console.log('rejecting', zipProcess)
reject(
new Error(
`Unexpected exit code from native zip command: ${exitCode}\n executed command '${command}'\n executed inin directory '${options.cwd ||
process.cwd()}'`
)
);
}
});
});
+188
View File
@@ -0,0 +1,188 @@
#!/usr/bin/env python3
"""Build vfc-js recipes from SecBench.js fix commits (maintainer, network via gh).
SecBench.js has no license file, so nothing from it is vendored. Its package.json
metadata names the upstream fix commit; the pair is harvested from that upstream
repository (hunk mode: the function enclosing the first changed hunk) and carries
the upstream package license. Crawl first:
python benchmarks/pairs/vfc-js/build_recipes.py --crawl /tmp/secbench.jsonl # lists modules with a GitHub fixCommit
python benchmarks/pairs/vfc-js/build_recipes.py --from /tmp/secbench.jsonl # resolves parent, license, changed file
python benchmarks/pairs/harvest.py --slice vfc-js --all --fetch
python benchmarks/pairs/catalog_gen.py --slice vfc-js
"""
from __future__ import annotations
import argparse
import base64
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parent
CLASSES = {
"command-injection": ("CWE-78", "command injection", "source_reaches_sink"),
"path-traversal": ("CWE-22", "path traversal", "path_join_user_input"),
"code-injection": ("CWE-94", "code injection", "source_reaches_sink"),
"prototype-pollution": ("CWE-1321", "prototype pollution", "prototype_pollution"),
"redos": ("CWE-1333", "regular expression denial of service", "redos"),
}
ACCEPTED_LICENSES = {"MIT", "Apache-2.0", "BSD-3-Clause", "BSD-2-Clause", "ISC", "MPL-2.0", "GPL-3.0", "GPL-2.0", "Unlicense", "0BSD"}
_JS = re.compile(r"\.(js|mjs|cjs|ts)$")
_SKIP = re.compile(r"(test|spec|\.d\.ts|dist/|build/|min\.js|package\.json|README)", re.I)
def _gh(path: str) -> object:
return json.loads(subprocess.check_output(["gh", "api", path], stderr=subprocess.DEVNULL))
def crawl(out: Path, classes: tuple[str, ...]) -> int:
count = 0
with out.open("w") as handle:
for cls in classes:
dirs = _gh(f"repos/cristianstaicu/SecBench.js/contents/{cls}")
for entry in dirs if isinstance(dirs, list) else []:
if entry.get("type") != "dir":
continue
time.sleep(0.4)
try:
raw = subprocess.check_output(
["gh", "api", f"repos/cristianstaicu/SecBench.js/contents/{cls}/{entry['name']}/package.json", "--jq", ".content"],
stderr=subprocess.DEVNULL,
)
meta = json.loads(base64.b64decode(raw))
except Exception: # noqa: BLE001 — skip unreadable modules
continue
fix = str(meta.get("fixCommit", "n/a"))
if "github.com" in fix and "/commit/" in fix:
handle.write(
json.dumps(
{"class": cls, "module": entry["name"], "cve": meta.get("id"), "fixCommit": fix, "sink": meta.get("sink")}
)
+ "\n"
)
count += 1
return count
def build(crawl_path: Path, *, limit: int) -> tuple[list[dict[str, object]], dict[str, int]]:
recipes: list[dict[str, object]] = []
skipped = {"unlicensed": 0, "no_js_file": 0, "api": 0, "multi_file": 0}
rows = [json.loads(line) for line in crawl_path.read_text().splitlines() if line.strip()]
seen_shas: set[str] = set()
seen_modules: set[str] = set()
skipped.update({"duplicate_fix": 0, "module_repo_mismatch": 0})
for row in rows:
if len(recipes) >= limit:
break
match = re.search(r"github\.com/([^/]+/[^/]+)/commit/([0-9a-f]{7,40})", row["fixCommit"])
if not match:
continue
repo, sha = match.group(1), match.group(2)
module_base = re.sub(r"[^a-z0-9]", "", str(row["module"]).rsplit("_", 1)[0].lower())
repo_base = re.sub(r"[^a-z0-9]", "", repo.split("/")[-1].lower())
if sha[:10] in seen_shas or str(row["module"]) in seen_modules:
skipped["duplicate_fix"] += 1 # SecBench.js records one upstream fix under several module names
continue
if module_base not in repo_base and repo_base not in module_base:
skipped["module_repo_mismatch"] += 1 # the fix commit belongs to another package; do not attribute
continue
seen_shas.add(sha[:10])
seen_modules.add(str(row["module"]))
time.sleep(0.6)
try:
commit = _gh(f"repos/{repo}/commits/{sha}")
info = _gh(f"repos/{repo}")
except Exception: # noqa: BLE001 — upstream gone or renamed
skipped["api"] += 1
continue
assert isinstance(commit, dict) and isinstance(info, dict)
license_id = (info.get("license") or {}).get("spdx_id") or ""
if license_id not in ACCEPTED_LICENSES:
skipped["unlicensed"] += 1
continue
files = [f for f in commit.get("files", []) if _JS.search(f["filename"]) and not _SKIP.search(f["filename"]) and f.get("patch")]
if not files:
skipped["no_js_file"] += 1
continue
if len(files) > 3:
skipped["multi_file"] += 1
continue
target = sorted(files, key=lambda f: -(f.get("additions", 0) + f.get("deletions", 0)))[0]
parents = commit.get("parents") or []
if not parents:
skipped["api"] += 1
continue
cwe, cls_text, mechanism = CLASSES[row["class"]]
module = str(row["module"])
name = f"{re.sub(r'[^a-z0-9]+', '-', module.lower()).strip('-')}"[:60]
recipes.append(
{
"name": name,
"host": "github",
"repo": repo,
"parent": parents[0]["sha"],
"commit": commit["sha"],
"path": target["filename"],
"mode": "hunk",
"language": "typescript" if target["filename"].endswith(".ts") else "javascript",
"relpath": target["filename"],
"license": license_id,
"cve": str(row.get("cve") or ""),
"year": int(str(commit["commit"]["author"]["date"])[:4]),
"cwe": cwe,
"class": cls_text,
"mechanism": mechanism,
"provenance": "human",
"origin": "secbench.js",
"project": module.rsplit("_", 1)[0],
"sink_location": str(row.get("sink") or ""),
"secbench_class": row["class"],
"evidence": f"SecBench.js {row['class']} sink {row.get('sink')} fixed upstream in {sha[:12]}",
"commit_url": f"https://github.com/{repo}/commit/{commit['sha']}",
}
)
for index, recipe in enumerate(sorted(recipes, key=lambda r: str(r["name"]))):
recipe["split"] = "holdout" if index % 2 else "train"
return recipes, skipped
def to_toml(recipes: list[dict[str, object]]) -> str:
lines = [
"# vfc-js harvest recipes derived from SecBench.js fixCommit metadata by build_recipes.py.",
"# Excerpts come from the upstream package repository (its license), never from SecBench.js.",
"",
]
for recipe in sorted(recipes, key=lambda r: str(r["name"])):
lines.append("[[recipe]]")
for key, value in recipe.items():
if isinstance(value, int) and not isinstance(value, bool):
lines.append(f"{key} = {value}")
else:
lines.append(f'{key} = "{str(value).replace(chr(92), chr(92) * 2).replace(chr(34), chr(92) + chr(34))}"')
lines.append("")
return "\n".join(lines)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--crawl", type=Path, help="write the SecBench.js module list with GitHub fix commits to this jsonl")
parser.add_argument("--classes", default="command-injection,path-traversal,code-injection")
parser.add_argument("--from", dest="source", type=Path, help="jsonl produced by --crawl")
parser.add_argument("--limit", type=int, default=40)
parser.add_argument("--out", type=Path, default=ROOT / "recipes.toml")
args = parser.parse_args(argv)
if args.crawl:
print(f"crawled {crawl(args.crawl, tuple(args.classes.split(',')))} modules -> {args.crawl}")
if args.source:
recipes, skipped = build(args.source, limit=args.limit)
args.out.write_text(to_toml(recipes), encoding="utf-8")
print(f"wrote {args.out} ({len(recipes)} recipes); skipped {skipped}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+493
View File
@@ -0,0 +1,493 @@
# vfc-js pair slice. Reviewed isolated functions with provenance.
# Honesty dashboard — not the local 100% CI gate.
# Do not add these names to LANGUAGE_MANIFESTS.
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
[[pair]]
name = "angular-http-server-1-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "Apache-2.0"
repo = "simonh1000/angular-http-server"
cve = ""
cwe = "CWE-22"
commit = "8bafc9577161469f5dea01e0b98ea9c525d063e9"
parent = "d171a771a92e4685b24fb77cb894a7b7b8024c5c"
commit_url = "https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9"
vuln = "angular-http-server-1-0-0/vuln.js"
fixed = "angular-http-server-1-0-0/fixed.js"
relpath = "angular-http-server.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "angular-http-server.js"
function = "requestListener"
mechanism = "path_join_user_input"
sink = "path"
evidence = "SecBench.js path-traversal sink angular-http-server.js:16:29 fixed upstream in 8bafc9577161"
[[pair]]
name = "apex-publish-static-files-2-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "vincentmorneau/apex-publish-static-files"
cve = "CVE-2018-16462"
cwe = "CWE-78"
commit = "2209af8f2b65c24aa55ab757e0e05b958c16f063"
parent = "8d28fe8a9a49e5ff3f61e239293b5646528e2915"
commit_url = "https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063"
vuln = "apex-publish-static-files-2-0-0/vuln.js"
fixed = "apex-publish-static-files-2-0-0/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "index.js"
function = "publish"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink index.js:54:25 fixed upstream in 2209af8f2b65"
[[pair]]
name = "bestzip-2-1-6"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "nfriedly/node-bestzip"
cve = "CVE-2020-7730"
cwe = "CWE-78"
commit = "45d4a901478c6a8f396c8b959dd6cf8fd3f955b6"
parent = "fcea252e52b6078eff6caf5531bd32c53fccb59f"
commit_url = "https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6"
vuln = "bestzip-2-1-6/vuln.js"
fixed = "bestzip-2-1-6/fixed.js"
relpath = "lib/bestzip.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "lib/bestzip.js"
function = "nativeZip"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink lib/bestzip.js:27:27 fixed upstream in 45d4a901478c"
[[pair]]
name = "clamscan-1-2-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "kylefarris/clamscan"
cve = "CVE-2020-7613"
cwe = "CWE-78"
commit = "5f557c970817fe8c578ec3f7ad3bcbcef4cf5538"
parent = "d474da7b89c0d3397cd681e79c7bcc592bff144b"
commit_url = "https://github.com/kylefarris/clamscan/commit/5f557c970817fe8c578ec3f7ad3bcbcef4cf5538"
vuln = "clamscan-1-2-0/vuln.js"
fixed = "clamscan-1-2-0/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "index.js"
function = "local_scan"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink index.js:495:36 fixed upstream in 5f557c970817"
[[pair]]
name = "diskusage-ng-0-2-6"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "iximiuz/node-diskusage-ng"
cve = "CVE-2020-7631"
cwe = "CWE-78"
commit = "48e7e093486b528f0c81ec699573e0e4a431b8d3"
parent = "53c505506553c83861d1bd67823d6a382d3a5a43"
commit_url = "https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3"
vuln = "diskusage-ng-0-2-6/vuln.js"
fixed = "diskusage-ng-0-2-6/fixed.js"
relpath = "lib/posix.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "lib/posix.js"
function = "diskusage"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink lib/posix.js:11:5 fixed upstream in 48e7e093486b"
[[pair]]
name = "dns-sync-0-1-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "skoranga/node-dns-sync"
cve = "CVE-2014-9682"
cwe = "CWE-78"
commit = "d9abaae384b198db1095735ad9c1c73d7b890a0d"
parent = "b748fe77a87749d95876028eda8e759109be4c73"
commit_url = "https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d"
vuln = "dns-sync-0-1-0/vuln.js"
fixed = "dns-sync-0-1-0/fixed.js"
relpath = "lib/dns-sync.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "lib/dns-sync.js"
function = "resolve"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink lib/dns-sync.js:21:26 fixed upstream in d9abaae384b1"
[[pair]]
name = "glance-3-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "jarofghosts/glance"
cve = "CVE-2018-3715"
cwe = "CWE-22"
commit = "8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19"
parent = "7e69a5539236386e747fb240ae87ea65ed64bb2c"
commit_url = "https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19"
vuln = "glance-3-0-0/vuln.js"
fixed = "glance-3-0-0/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "index.js"
function = "Glance$serveRequest"
mechanism = "path_join_user_input"
evidence = "SecBench.js path-traversal sink index.js:81:14 fixed upstream in 8cfd88e44ebd"
[[pair]]
name = "hot-formula-parser-3-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "handsontable/formula-parser"
cve = "CVE-2020-6836"
cwe = "CWE-78"
commit = "396b089738d4bf30eb570a4fe6a188affa95cd5e"
parent = "944136096f44ff4ffd4ba0bcef30970ca4702fce"
commit_url = "https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e"
vuln = "hot-formula-parser-3-0-0/vuln.js"
fixed = "hot-formula-parser-3-0-0/fixed.js"
relpath = "src/grammar-parser/grammar-parser.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "src/grammar-parser/grammar-parser.js"
function = "performAction"
mechanism = "source_reaches_sink"
evidence = "SecBench.js command-injection sink lib/grammar-parser/grammar-parser.js:258:31 fixed upstream in 396b089738d4"
[[pair]]
name = "libnmap-0-4-11"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "jas-/node-libnmap"
cve = "CVE-2018-16461"
cwe = "CWE-78"
commit = "c235b24b0342e12a5dbf502f89daabe95883b6c8"
parent = "49b72239b144ab7ffdf673b62e18bfd0760948f6"
commit_url = "https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8"
vuln = "libnmap-0-4-11/vuln.js"
fixed = "libnmap-0-4-11/fixed.js"
relpath = "lib/classes/tools.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "lib/classes/tools.js"
function = "block"
mechanism = "source_reaches_sink"
evidence = "SecBench.js command-injection sink lib/classes/tools.js:114:25 fixed upstream in c235b24b0342"
[[pair]]
name = "pdf-image-1-0-5"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "roest01/node-pdf-image"
cve = "CVE-2018-3757"
cwe = "CWE-78"
commit = "54679496a89738443917608c2bbe2f6e5dd20e83"
parent = "d8c0dcadd93985dbefe80b84060f5f572bfbb6ff"
commit_url = "https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83"
vuln = "pdf-image-1-0-5/vuln.js"
fixed = "pdf-image-1-0-5/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "index.js"
function = "getInfo"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink index.js:43:7 fixed upstream in 54679496a897"
[[pair]]
name = "pidusage-1-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "soyuka/pidusage"
cve = "CVE-2017-16034"
cwe = "CWE-78"
commit = "b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d"
parent = "e3660d8a8e5e61afad9b02af67356a1e239d6bde"
commit_url = "https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d"
vuln = "pidusage-1-0-0/vuln.js"
fixed = "pidusage-1-0-0/fixed.js"
relpath = "lib/stats.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "lib/stats.js"
function = "ps"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink lib/stats.js:108:5 fixed upstream in b70eca15f7ca"
[[pair]]
name = "portprocesses-1-0-4"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "rrainn/PortProcesses"
cve = "CVE-2021-23348"
cwe = "CWE-78"
commit = "86811216c9b97b01b5722f879f8c88a7aa4214e1"
parent = "fffceb09aff7180afbd0bd172e820404b33c8299"
commit_url = "https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1"
vuln = "portprocesses-1-0-4/vuln.js"
fixed = "portprocesses-1-0-4/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "index.js"
function = "listProcessesOnPort"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink exec.js:5:3 fixed upstream in 86811216c9b9"
[[pair]]
name = "serve-here-js-1-1-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "ChristoPy/serve-here.js"
cve = "CVE-2019-5444"
cwe = "CWE-22"
commit = "cefb51d03290b6a88dd13143ab2de31b8cf57c39"
parent = "ad077637bf7a9fe0dee3262f011aed19a45ce92c"
commit_url = "https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39"
vuln = "serve-here-js-1-1-0/vuln.js"
fixed = "serve-here-js-1-1-0/fixed.js"
relpath = "source/response.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-22"
class = "path traversal"
path = "source/response.js"
function = "ConfigureFilePath"
mechanism = "path_join_user_input"
evidence = "SecBench.js path-traversal sink source/server.js:27:15 fixed upstream in cefb51d03290"
[[pair]]
name = "static-eval-1-1-1"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "browserify/static-eval"
cve = ""
cwe = "CWE-94"
commit = "32f8efd072625e267aa7237d2daff35738c50d2a"
parent = "5bba7905b0e797460b8f6c2e38ff6869146faab3"
commit_url = "https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a"
vuln = "static-eval-1-1-1/vuln.js"
fixed = "static-eval-1-1-1/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-94"
class = "code injection"
path = "index.js"
function = "walk"
mechanism = "source_reaches_sink"
sink = "eval"
evidence = "SecBench.js code-injection sink index.js:118:20 fixed upstream in 32f8efd07262"
[[pair]]
name = "thenify-3-3-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "thenables/thenify"
cve = "CVE-2020-7677"
cwe = "CWE-94"
commit = "0d94a24eb933bc835d568f3009f4d269c4c4c17a"
parent = "aa21cfb64f47238c764d258d0faf7366a8487e36"
commit_url = "https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a"
vuln = "thenify-3-3-0/vuln.js"
fixed = "thenify-3-3-0/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-94"
class = "code injection"
path = "index.js"
function = "thenify"
mechanism = "source_reaches_sink"
sink = "eval"
evidence = "SecBench.js code-injection sink index.js:17:10 fixed upstream in 0d94a24eb933"
[[pair]]
name = "underscore-1-13-0-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "jashkenas/underscore"
cve = "CVE-2021-23358"
cwe = "CWE-94"
commit = "4c73526d43838ad6ab43a6134728776632adeb66"
parent = "ef646ccbbbd971e82719c83fc69f56a5585b3a01"
commit_url = "https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66"
vuln = "underscore-1-13-0-0/vuln.js"
fixed = "underscore-1-13-0-0/fixed.js"
relpath = "modules/template.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "train"
[[pair.expected]]
cwe = "CWE-94"
class = "code injection"
path = "modules/template.js"
function = "template"
mechanism = "source_reaches_sink"
sink = "eval"
evidence = "SecBench.js code-injection sink modules/template.js:71:14 fixed upstream in 4c73526d4383"
[[pair]]
name = "whereis-0-4-0"
slice = "vfc-js"
language = "javascript"
origin = "secbench.js"
license = "MIT"
repo = "vvo/node-whereis"
cve = "CVE-2018-3772"
cwe = "CWE-78"
commit = "0f64e3780235004fb6e43bfd153ea3e0e210ee2b"
parent = "b8b642b1163baa37f15ed49b4064dcbdb6e1876c"
commit_url = "https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b"
vuln = "whereis-0-4-0/vuln.js"
fixed = "whereis-0-4-0/fixed.js"
relpath = "index.js"
min_recall = 1.0
fix_policy = "silent"
provenance = "human"
split = "holdout"
[[pair.expected]]
cwe = "CWE-78"
class = "command injection"
path = "index.js"
function = "whereis"
mechanism = "source_reaches_sink"
sink = "exec"
evidence = "SecBench.js command-injection sink index.js:4:6 fixed upstream in 0f64e3780235"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
// Provenance: iximiuz/node-diskusage-ng (fixed).
// repo: iximiuz/node-diskusage-ng
// commit: 48e7e093486b528f0c81ec699573e0e4a431b8d3
// parent: 53c505506553c83861d1bd67823d6a382d3a5a43
// commit_url: https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3
// cve: CVE-2020-7631
// license: MIT
// function: diskusage
// relpath: lib/posix.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 6
function diskusage(path, cb) {
execFile('df', ['-k', path], function(err, stdout) {
if (err) {
return cb(err);
}
try {
cb(null, parse(stdout));
} catch (e) {
cb(e);
}
});
}
@@ -0,0 +1,30 @@
// Provenance: iximiuz/node-diskusage-ng (vuln).
// repo: iximiuz/node-diskusage-ng
// commit: 53c505506553c83861d1bd67823d6a382d3a5a43
// parent: 53c505506553c83861d1bd67823d6a382d3a5a43
// commit_url: https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3
// cve: CVE-2020-7631
// license: MIT
// function: diskusage
// relpath: lib/posix.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 6
function diskusage(path, cb) {
if (path.indexOf('"') !== -1) {
return cb(new Error('Paths with double quotes are not supported yet'));
}
exec('df -k "' + path + '"', function(err, stdout) {
if (err) {
return cb(err);
}
try {
cb(null, parse(stdout));
} catch (e) {
cb(e);
}
});
}
@@ -0,0 +1,38 @@
// Provenance: skoranga/node-dns-sync (fixed).
// repo: skoranga/node-dns-sync
// commit: d9abaae384b198db1095735ad9c1c73d7b890a0d
// parent: b748fe77a87749d95876028eda8e759109be4c73
// commit_url: https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d
// cve: CVE-2014-9682
// license: MIT
// function: resolve
// relpath: lib/dns-sync.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 19
module.exports = {
resolve: function resolve(hostname) {
var output,
nodeBinary = process.execPath;
if (!isValidHostName(hostname)) {
console.error('Invalid hostname:', hostname);
return null;
}
var scriptPath = path.join(__dirname, "../scripts/dns-lookup-script"),
response,
cmd = util.format('"%s" "%s" %s', nodeBinary, scriptPath, hostname);
response = shell.exec(cmd, {silent: true});
if (response && response.code === 0) {
output = response.output;
if (output && net.isIP(output)) {
return output;
}
}
debug('hostname', "fail to resolve hostname " + hostname);
return null;
}
};
@@ -0,0 +1,32 @@
// Provenance: skoranga/node-dns-sync (vuln).
// repo: skoranga/node-dns-sync
// commit: b748fe77a87749d95876028eda8e759109be4c73
// parent: b748fe77a87749d95876028eda8e759109be4c73
// commit_url: https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d
// cve: CVE-2014-9682
// license: MIT
// function: resolve
// relpath: lib/dns-sync.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 13
module.exports = {
resolve: function resolve(hostname) {
var output,
nodeBinary = process.execPath,
scriptPath = path.join(__dirname, "../scripts/dns-lookup-script"),
response,
cmd = util.format('"%s" "%s" %s', nodeBinary, scriptPath, hostname);
response = shell.exec(cmd, {silent: true});
if (response && response.code === 0) {
output = response.output;
if (output && net.isIP(output)) {
return output;
}
}
debug('hostname', "fail to resolve hostname " + hostname);
return null;
}
};
@@ -0,0 +1,92 @@
// Provenance: jarofghosts/glance (fixed).
// repo: jarofghosts/glance
// commit: 8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19
// parent: 7e69a5539236386e747fb240ae87ea65ed64bb2c
// commit_url: https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19
// cve: CVE-2018-3715
// license: MIT
// function: Glance$serveRequest
// relpath: index.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 60
Glance.prototype.serveRequest = function Glance$serveRequest (req, res) {
var request = {}
var self = this
request.fullPath = path.join(
self.dir,
decodeURIComponent(parse(req.url).pathname)
)
request.ip = req.socket.remoteAddress
request.method = req.method.toLowerCase()
request.response = res
// prevent traversing directories that are parents of the root
if (request.fullPath.slice(0, self.dir.length) !== self.dir) {
return self.emit('error', 403, request, res)
}
if (request.method !== 'get') {
return self.emit('error', 405, request, res)
}
if (self.nodot && /^\./.test(path.basename(request.fullPath))) {
return self.emit('error', 404, request, res)
}
fs.stat(request.fullPath, statFile)
function statFile (err, stat) {
if (err) {
return self.emit('error', 404, request, res)
}
if (!stat.isDirectory()) {
self.emit('read', request)
return filed(request.fullPath).pipe(res)
}
if (self.hideindex) {
return self.emit('error', 403, request, res)
}
if (!self.indices || !self.indices.length) {
return listFiles()
}
var indices = self.indices.slice()
findIndex(indices.shift())
function findIndex (indexTest) {
fileExists(path.join(request.fullPath, indexTest), check)
function check (hasIndex) {
if (hasIndex) {
req.url = req.url + '/' + indexTest
return self.serveRequest(req, res)
}
if (!indices.length) {
return listFiles()
}
findIndex(indices.shift())
}
}
function listFiles () {
var listPath = request.fullPath.replace(/\/$/, '')
res.writeHead(200, RESPONSE_HEADERS)
htmlls(listPath, {hideDot: self.nodot}).pipe(res)
return self.emit('read', request)
}
}
}
@@ -0,0 +1,87 @@
// Provenance: jarofghosts/glance (vuln).
// repo: jarofghosts/glance
// commit: 7e69a5539236386e747fb240ae87ea65ed64bb2c
// parent: 7e69a5539236386e747fb240ae87ea65ed64bb2c
// commit_url: https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19
// cve: CVE-2018-3715
// license: MIT
// function: Glance$serveRequest
// relpath: index.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 60
Glance.prototype.serveRequest = function Glance$serveRequest (req, res) {
var request = {}
var self = this
request.fullPath = path.join(
self.dir,
decodeURIComponent(parse(req.url).pathname)
)
request.ip = req.socket.remoteAddress
request.method = req.method.toLowerCase()
request.response = res
if (request.method !== 'get') {
return self.emit('error', 405, request, res)
}
if (self.nodot && /^\./.test(path.basename(request.fullPath))) {
return self.emit('error', 404, request, res)
}
fs.stat(request.fullPath, statFile)
function statFile (err, stat) {
if (err) {
return self.emit('error', 404, request, res)
}
if (!stat.isDirectory()) {
self.emit('read', request)
return filed(request.fullPath).pipe(res)
}
if (self.hideindex) {
return self.emit('error', 403, request, res)
}
if (!self.indices || !self.indices.length) {
return listFiles()
}
var indices = self.indices.slice()
findIndex(indices.shift())
function findIndex (indexTest) {
fileExists(path.join(request.fullPath, indexTest), check)
function check (hasIndex) {
if (hasIndex) {
req.url = req.url + '/' + indexTest
return self.serveRequest(req, res)
}
if (!indices.length) {
return listFiles()
}
findIndex(indices.shift())
}
}
function listFiles () {
var listPath = request.fullPath.replace(/\/$/, '')
res.writeHead(200, RESPONSE_HEADERS)
htmlls(listPath, {hideDot: self.nodot}).pipe(res)
return self.emit('read', request)
}
}
}
@@ -0,0 +1,867 @@
// Provenance: handsontable/formula-parser (fixed).
// repo: handsontable/formula-parser
// commit: 396b089738d4bf30eb570a4fe6a188affa95cd5e
// parent: 944136096f44ff4ffd4ba0bcef30970ca4702fce
// commit_url: https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e
// cve: CVE-2020-6836
// license: MIT
// function: performAction
// relpath: src/grammar-parser/grammar-parser.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 74
var grammarParser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,8],$V2=[1,6],$V3=[1,7],$V4=[1,9],$V5=[1,14],$V6=[1,15],$V7=[1,16],$V8=[1,12],$V9=[1,13],$Va=[1,17],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,22],$Vf=[1,23],$Vg=[1,24],$Vh=[1,25],$Vi=[1,26],$Vj=[1,27],$Vk=[1,28],$Vl=[5,9,10,11,13,14,15,16,17,18,19,20,29,30],$Vm=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,32],$Vn=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,34],$Vo=[5,10,11,13,14,15,16,17,29,30],$Vp=[5,10,13,14,15,16,29,30],$Vq=[5,10,11,13,14,15,16,17,18,19,29,30],$Vr=[13,29,30];
var parser = {trace: function trace () { },
yy: {},
symbols_: {"error":2,"expressions":3,"expression":4,"EOF":5,"variableSequence":6,"number":7,"STRING":8,"&":9,"=":10,"+":11,"(":12,")":13,"<":14,">":15,"NOT":16,"-":17,"*":18,"/":19,"^":20,"FUNCTION":21,"expseq":22,"cell":23,"ABSOLUTE_CELL":24,"RELATIVE_CELL":25,"MIXED_CELL":26,":":27,"ARRAY":28,";":29,",":30,"VARIABLE":31,"DECIMAL":32,"NUMBER":33,"%":34,"ERROR":35,"$accept":0,"$end":1},
terminals_: {5:"EOF",8:"STRING",9:"&",10:"=",11:"+",12:"(",13:")",14:"<",15:">",16:"NOT",17:"-",18:"*",19:"/",20:"^",21:"FUNCTION",24:"ABSOLUTE_CELL",25:"RELATIVE_CELL",26:"MIXED_CELL",27:":",28:"ARRAY",29:";",30:",",31:"VARIABLE",32:"DECIMAL",33:"NUMBER",34:"%",35:"ERROR"},
productions_: [0,[3,2],[4,1],[4,1],[4,1],[4,3],[4,3],[4,3],[4,3],[4,4],[4,4],[4,4],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,2],[4,2],[4,3],[4,4],[4,1],[4,1],[4,2],[23,1],[23,1],[23,1],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[22,1],[22,1],[22,3],[22,3],[6,1],[6,3],[7,1],[7,3],[7,2],[2,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return $$[$0-1];
break;
case 2:
this.$ = yy.callVariable($$[$0][0]);
break;
case 3:
this.$ = yy.toNumber($$[$0]);
break;
case 4:
this.$ = yy.trimEdges($$[$0]);
break;
case 5:
this.$ = yy.evaluateByOperator('&', [$$[$0-2], $$[$0]]);
break;
case 6:
this.$ = yy.evaluateByOperator('=', [$$[$0-2], $$[$0]]);
break;
case 7:
this.$ = yy.evaluateByOperator('+', [$$[$0-2], $$[$0]]);
break;
case 8:
this.$ = $$[$0-1];
break;
case 9:
this.$ = yy.evaluateByOperator('<=', [$$[$0-3], $$[$0]]);
break;
case 10:
this.$ = yy.evaluateByOperator('>=', [$$[$0-3], $$[$0]]);
break;
case 11:
this.$ = yy.evaluateByOperator('<>', [$$[$0-3], $$[$0]]);
break;
case 12:
this.$ = yy.evaluateByOperator('NOT', [$$[$0-2], $$[$0]]);
break;
case 13:
this.$ = yy.evaluateByOperator('>', [$$[$0-2], $$[$0]]);
break;
case 14:
this.$ = yy.evaluateByOperator('<', [$$[$0-2], $$[$0]]);
break;
case 15:
this.$ = yy.evaluateByOperator('-', [$$[$0-2], $$[$0]]);
break;
case 16:
this.$ = yy.evaluateByOperator('*', [$$[$0-2], $$[$0]]);
break;
case 17:
this.$ = yy.evaluateByOperator('/', [$$[$0-2], $$[$0]]);
break;
case 18:
this.$ = yy.evaluateByOperator('^', [$$[$0-2], $$[$0]]);
break;
case 19:
var n1 = yy.invertNumber($$[$0]);
this.$ = n1;
if (isNaN(this.$)) {
this.$ = 0;
}
break;
case 20:
var n1 = yy.toNumber($$[$0]);
this.$ = n1;
if (isNaN(this.$)) {
this.$ = 0;
}
break;
case 21:
this.$ = yy.callFunction($$[$0-2]);
break;
case 22:
this.$ = yy.callFunction($$[$0-3], $$[$0-1]);
break;
case 26: case 27: case 28:
this.$ = yy.cellValue($$[$0]);
break;
case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37:
this.$ = yy.rangeValue($$[$0-2], $$[$0]);
break;
case 38: case 42:
this.$ = [$$[$0]];
break;
case 39:
this.$ = yy.trimEdges(yytext).split(',');
break;
case 40: case 41:
$$[$0-2].push($$[$0]);
this.$ = $$[$0-2];
break;
case 43:
this.$ = (Array.isArray($$[$0-2]) ? $$[$0-2] : [$$[$0-2]]);
this.$.push($$[$0]);
break;
case 44:
this.$ = $$[$0];
break;
case 45:
this.$ = ($$[$0-2] + '.' + $$[$0]) * 1;
break;
case 46:
this.$ = $$[$0-1] * 0.01;
break;
case 47:
this.$ = yy.throwError($$[$0]);
break;
}
},
table: [{2:11,3:1,4:2,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{1:[3]},{5:[1,18],9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vl,[2,2],{32:[1,29]}),o($Vl,[2,3],{34:[1,30]}),o($Vl,[2,4]),{2:11,4:31,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:32,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:33,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{12:[1,34]},o($Vl,[2,23]),o($Vl,[2,24],{2:35,35:$Va}),o($Vm,[2,42]),o($Vn,[2,44],{32:[1,36]}),o($Vl,[2,26],{27:[1,37]}),o($Vl,[2,27],{27:[1,38]}),o($Vl,[2,28],{27:[1,39]}),o([5,9,10,11,13,14,15,16,17,18,19,20,29,30,35],[2,47]),{1:[2,1]},{2:11,4:40,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:41,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:42,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:45,6:3,7:4,8:$V0,10:[1,43],11:$V1,12:$V2,15:[1,44],17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:47,6:3,7:4,8:$V0,10:[1,46],11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:48,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:49,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:50,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:51,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:52,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{31:[1,53]},o($Vn,[2,46]),{9:$Vb,10:$Vc,11:$Vd,13:[1,54],14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vo,[2,19],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,20],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:57,6:3,7:4,8:$V0,11:$V1,12:$V2,13:[1,55],17:$V3,21:$V4,22:56,23:10,24:$V5,25:$V6,26:$V7,28:[1,58],31:$V8,33:$V9,35:$Va},o($Vl,[2,25]),{33:[1,59]},{24:[1,60],25:[1,61],26:[1,62]},{24:[1,63],25:[1,64],26:[1,65]},{24:[1,66],25:[1,67],26:[1,68]},o($Vl,[2,5]),o([5,10,13,29,30],[2,6],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,7],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:69,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:70,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,14],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:71,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,13],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o([5,10,13,16,29,30],[2,12],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,15],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vq,[2,16],{9:$Vb,20:$Vk}),o($Vq,[2,17],{9:$Vb,20:$Vk}),o([5,10,11,13,14,15,16,17,18,19,20,29,30],[2,18],{9:$Vb}),o($Vm,[2,43]),o($Vl,[2,8]),o($Vl,[2,21]),{13:[1,72],29:[1,73],30:[1,74]},o($Vr,[2,38],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,39]),o($Vn,[2,45]),o($Vl,[2,29]),o($Vl,[2,30]),o($Vl,[2,31]),o($Vl,[2,32]),o($Vl,[2,33]),o($Vl,[2,34]),o($Vl,[2,35]),o($Vl,[2,36]),o($Vl,[2,37]),o($Vp,[2,9],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,11],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,10],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vl,[2,22]),{2:11,4:75,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:76,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vr,[2,40],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,41],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk})],
defaultActions: {18:[2,1]},
parseError: function parseError (str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
var error = new Error(str);
error.hash = hash;
throw error;
}
},
parse: function parse (input) {
var self = this,
stack = [0],
tstack = [], // token stack
vstack = [null], // semantic value stack
lstack = [], // location stack
table = this.table,
yytext = '',
yylineno = 0,
yyleng = 0,
recovering = 0,
TERROR = 2,
EOF = 1;
var args = lstack.slice.call(arguments, 1);
//this.reductionCount = this.shiftCount = 0;
var lexer = Object.create(this.lexer);
var sharedState = { yy: {} };
// copy state
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function popStack (n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
_token_stack:
var lex = function () {
var token;
token = lexer.lex() || EOF;
// if token isn't its numeric value, convert
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
}
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) {
// retreive state number from top of stack
state = stack[stack.length - 1];
// use default actions if available
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
// read action for current state and first input
action = table[state] && table[state][symbol];
}
_handle_error:
// handle parse error
if (typeof action === 'undefined' || !action.length || !action[0]) {
var error_rule_depth;
var errStr = '';
// Return the rule stack depth where the nearest error rule can be found.
// Return FALSE when no error recovery rule was found.
function locateNearestErrorRecoveryRule(state) {
var stack_probe = stack.length - 1;
var depth = 0;
// try to recover from error
for(;;) {
// check for error recovery rule in this state
if ((TERROR.toString()) in table[state]) {
return depth;
}
if (state === 0 || stack_probe < 2) {
return false; // No suitable error recovery rule available.
}
stack_probe -= 2; // popStack(1): [symbol, action]
state = stack[stack_probe];
++depth;
}
}
if (!recovering) {
// first see if there's any chance at hitting an error recovery rule:
error_rule_depth = locateNearestErrorRecoveryRule(state);
// Report error
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push("'"+this.terminals_[p]+"'");
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line '+(yylineno+1)+":\n"+lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol)+ "'";
} else {
errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
(symbol == EOF ? "end of input" :
("'"+(this.terminals_[symbol] || symbol)+"'"));
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected,
recoverable: (error_rule_depth !== false)
});
} else if (preErrorSymbol !== EOF) {
error_rule_depth = locateNearestErrorRecoveryRule(state);
}
// just recovered from another error
if (recovering == 3) {
if (symbol === EOF || preErrorSymbol === EOF) {
throw new Error(errStr || 'Parsing halted while starting to recover from another error.');
}
// discard current lookahead and grab another
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
symbol = lex();
}
// try to recover from error
if (error_rule_depth === false) {
throw new Error(errStr || 'Parsing halted. No suitable error recovery rule available.');
}
popStack(error_rule_depth);
preErrorSymbol = (symbol == TERROR ? null : symbol); // save the lookahead token
symbol = TERROR; // insert generic error symbol as new lookahead
state = stack[stack.length-1];
action = table[state] && table[state][TERROR];
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
}
// this shouldn't happen, unless resolve defaults are off
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
}
switch (action[0]) {
case 1: // shift
//this.shiftCount++;
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]); // push state
symbol = null;
if (!preErrorSymbol) { // normal execution/no error
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
} else {
// error just occurred, resume old lookahead f/ before error
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
// reduce
//this.reductionCount++;
len = this.productions_[action[1]][1];
// perform semantic action
yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
// default location, uses first token for firsts, last for lasts
yyval._$ = {
first_line: lstack[lstack.length-(len||1)].first_line,
last_line: lstack[lstack.length-1].last_line,
first_column: lstack[lstack.length-(len||1)].first_column,
last_column: lstack[lstack.length-1].last_column
};
if (ranges) {
yyval._$.range = [lstack[lstack.length-(len||1)].range[0], lstack[lstack.length-1].range[1]];
}
r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));
if (typeof r !== 'undefined') {
return r;
}
// pop off stack
if (len) {
stack = stack.slice(0,-1*len*2);
vstack = vstack.slice(0, -1*len);
lstack = lstack.slice(0, -1*len);
}
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
vstack.push(yyval.$);
lstack.push(yyval._$);
// goto new state = table[STATE][NONTERMINAL]
newState = table[stack[stack.length-2]][stack[stack.length-1]];
stack.push(newState);
break;
case 3:
// accept
return true;
}
}
return true;
}};
/* generated by jison-lex 0.3.4 */
var lexer = (function(){
var lexer = ({
EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput:function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0,0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input:function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput:function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more:function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject:function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less:function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function(match, indexed_rule) {
var token,
lines,
backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token,
match,
tempMatch,
index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex:function lex () {
var r = this.next();
if (r) {
return r;
} else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin (condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState:function popState () {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules () {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
} else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState (n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState:function pushState (condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize:function stateStackSize() {
return this.conditionStack.length;
},
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 8;
break;
case 2:return 8;
break;
case 3:return 21;
break;
case 4:return 35;
break;
case 5:return 24;
break;
case 6:return 26;
break;
case 7:return 26;
break;
case 8:return 25;
break;
case 9:return 21;
break;
case 10:return 31;
break;
case 11:return 31;
break;
case 12:return 33;
break;
case 13:return 28;
break;
case 14:return 9;
break;
case 15:return ' ';
break;
case 16:return 32;
break;
case 17:return 27;
break;
case 18:return 29;
break;
case 19:return 30;
break;
case 20:return 18;
break;
case 21:return 19;
break;
case 22:return 17;
break;
case 23:return 11;
break;
case 24:return 20;
break;
case 25:return 12;
break;
case 26:return 13;
break;
case 27:return 15;
break;
case 28:return 14;
break;
case 29:return 16;
break;
case 30:return '"';
break;
case 31:return "'";
break;
case 32:return "!";
break;
case 33:return 10;
break;
case 34:return 34;
break;
case 35:return '#';
break;
case 36:return 5;
break;
}
},
rules: [/^(?:\s+)/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9\.]+(?=[(]))/,/^(?:#[A-Z0-9\/]+(!|\?)?)/,/^(?:\$[A-Za-z]+\$[0-9]+)/,/^(?:\$[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z]+\$[0-9]+)/,/^(?:[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z\.]+(?=[(]))/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)/,/^(?:[A-Za-z_]+)/,/^(?:[0-9]+)/,/^(?:\[(.*)?\])/,/^(?:&)/,/^(?: )/,/^(?:[.])/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\/)/,/^(?:-)/,/^(?:\+)/,/^(?:\^)/,/^(?:\()/,/^(?:\))/,/^(?:>)/,/^(?:<)/,/^(?:NOT\b)/,/^(?:")/,/^(?:')/,/^(?:!)/,/^(?:=)/,/^(?:%)/,/^(?:[#])/,/^(?:$)/],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"inclusive":true}}
});
return lexer;
})();
parser.lexer = lexer;
function Parser () {
this.yy = {};
}
Parser.prototype = parser;parser.Parser = Parser;
return new Parser;
})();
@@ -0,0 +1,876 @@
// Provenance: handsontable/formula-parser (vuln).
// repo: handsontable/formula-parser
// commit: 944136096f44ff4ffd4ba0bcef30970ca4702fce
// parent: 944136096f44ff4ffd4ba0bcef30970ca4702fce
// commit_url: https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e
// cve: CVE-2020-6836
// license: MIT
// function: performAction
// relpath: src/grammar-parser/grammar-parser.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 74
var grammarParser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,8],$V2=[1,6],$V3=[1,7],$V4=[1,9],$V5=[1,14],$V6=[1,15],$V7=[1,16],$V8=[1,12],$V9=[1,13],$Va=[1,17],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,22],$Vf=[1,23],$Vg=[1,24],$Vh=[1,25],$Vi=[1,26],$Vj=[1,27],$Vk=[1,28],$Vl=[5,9,10,11,13,14,15,16,17,18,19,20,29,30],$Vm=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,32],$Vn=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,34],$Vo=[5,10,11,13,14,15,16,17,29,30],$Vp=[5,10,13,14,15,16,29,30],$Vq=[5,10,11,13,14,15,16,17,18,19,29,30],$Vr=[13,29,30];
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"expressions":3,"expression":4,"EOF":5,"variableSequence":6,"number":7,"STRING":8,"&":9,"=":10,"+":11,"(":12,")":13,"<":14,">":15,"NOT":16,"-":17,"*":18,"/":19,"^":20,"FUNCTION":21,"expseq":22,"cell":23,"ABSOLUTE_CELL":24,"RELATIVE_CELL":25,"MIXED_CELL":26,":":27,"ARRAY":28,";":29,",":30,"VARIABLE":31,"DECIMAL":32,"NUMBER":33,"%":34,"ERROR":35,"$accept":0,"$end":1},
terminals_: {5:"EOF",8:"STRING",9:"&",10:"=",11:"+",12:"(",13:")",14:"<",15:">",16:"NOT",17:"-",18:"*",19:"/",20:"^",21:"FUNCTION",24:"ABSOLUTE_CELL",25:"RELATIVE_CELL",26:"MIXED_CELL",27:":",28:"ARRAY",29:";",30:",",31:"VARIABLE",32:"DECIMAL",33:"NUMBER",34:"%",35:"ERROR"},
productions_: [0,[3,2],[4,1],[4,1],[4,1],[4,3],[4,3],[4,3],[4,3],[4,4],[4,4],[4,4],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,2],[4,2],[4,3],[4,4],[4,1],[4,1],[4,2],[23,1],[23,1],[23,1],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[22,1],[22,1],[22,3],[22,3],[6,1],[6,3],[7,1],[7,3],[7,2],[2,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return $$[$0-1];
break;
case 2:
this.$ = yy.callVariable($$[$0][0]);
break;
case 3:
this.$ = yy.toNumber($$[$0]);
break;
case 4:
this.$ = yy.trimEdges($$[$0]);
break;
case 5:
this.$ = yy.evaluateByOperator('&', [$$[$0-2], $$[$0]]);
break;
case 6:
this.$ = yy.evaluateByOperator('=', [$$[$0-2], $$[$0]]);
break;
case 7:
this.$ = yy.evaluateByOperator('+', [$$[$0-2], $$[$0]]);
break;
case 8:
this.$ = $$[$0-1];
break;
case 9:
this.$ = yy.evaluateByOperator('<=', [$$[$0-3], $$[$0]]);
break;
case 10:
this.$ = yy.evaluateByOperator('>=', [$$[$0-3], $$[$0]]);
break;
case 11:
this.$ = yy.evaluateByOperator('<>', [$$[$0-3], $$[$0]]);
break;
case 12:
this.$ = yy.evaluateByOperator('NOT', [$$[$0-2], $$[$0]]);
break;
case 13:
this.$ = yy.evaluateByOperator('>', [$$[$0-2], $$[$0]]);
break;
case 14:
this.$ = yy.evaluateByOperator('<', [$$[$0-2], $$[$0]]);
break;
case 15:
this.$ = yy.evaluateByOperator('-', [$$[$0-2], $$[$0]]);
break;
case 16:
this.$ = yy.evaluateByOperator('*', [$$[$0-2], $$[$0]]);
break;
case 17:
this.$ = yy.evaluateByOperator('/', [$$[$0-2], $$[$0]]);
break;
case 18:
this.$ = yy.evaluateByOperator('^', [$$[$0-2], $$[$0]]);
break;
case 19:
var n1 = yy.invertNumber($$[$0]);
this.$ = n1;
if (isNaN(this.$)) {
this.$ = 0;
}
break;
case 20:
var n1 = yy.toNumber($$[$0]);
this.$ = n1;
if (isNaN(this.$)) {
this.$ = 0;
}
break;
case 21:
this.$ = yy.callFunction($$[$0-2]);
break;
case 22:
this.$ = yy.callFunction($$[$0-3], $$[$0-1]);
break;
case 26: case 27: case 28:
this.$ = yy.cellValue($$[$0]);
break;
case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37:
this.$ = yy.rangeValue($$[$0-2], $$[$0]);
break;
case 38: case 42:
this.$ = [$$[$0]];
break;
case 39:
var result = [];
var arr = eval("[" + yytext + "]");
arr.forEach(function(item) {
result.push(item);
});
this.$ = result;
break;
case 40: case 41:
$$[$0-2].push($$[$0]);
this.$ = $$[$0-2];
break;
case 43:
this.$ = (Array.isArray($$[$0-2]) ? $$[$0-2] : [$$[$0-2]]);
this.$.push($$[$0]);
break;
case 44:
this.$ = $$[$0];
break;
case 45:
this.$ = ($$[$0-2] + '.' + $$[$0]) * 1;
break;
case 46:
this.$ = $$[$0-1] * 0.01;
break;
case 47:
this.$ = yy.throwError($$[$0]);
break;
}
},
table: [{2:11,3:1,4:2,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{1:[3]},{5:[1,18],9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vl,[2,2],{32:[1,29]}),o($Vl,[2,3],{34:[1,30]}),o($Vl,[2,4]),{2:11,4:31,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:32,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:33,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{12:[1,34]},o($Vl,[2,23]),o($Vl,[2,24],{2:35,35:$Va}),o($Vm,[2,42]),o($Vn,[2,44],{32:[1,36]}),o($Vl,[2,26],{27:[1,37]}),o($Vl,[2,27],{27:[1,38]}),o($Vl,[2,28],{27:[1,39]}),o([5,9,10,11,13,14,15,16,17,18,19,20,29,30,35],[2,47]),{1:[2,1]},{2:11,4:40,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:41,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:42,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:45,6:3,7:4,8:$V0,10:[1,43],11:$V1,12:$V2,15:[1,44],17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:47,6:3,7:4,8:$V0,10:[1,46],11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:48,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:49,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:50,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:51,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:52,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{31:[1,53]},o($Vn,[2,46]),{9:$Vb,10:$Vc,11:$Vd,13:[1,54],14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vo,[2,19],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,20],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:57,6:3,7:4,8:$V0,11:$V1,12:$V2,13:[1,55],17:$V3,21:$V4,22:56,23:10,24:$V5,25:$V6,26:$V7,28:[1,58],31:$V8,33:$V9,35:$Va},o($Vl,[2,25]),{33:[1,59]},{24:[1,60],25:[1,61],26:[1,62]},{24:[1,63],25:[1,64],26:[1,65]},{24:[1,66],25:[1,67],26:[1,68]},o($Vl,[2,5]),o([5,10,13,29,30],[2,6],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,7],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:69,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:70,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,14],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:71,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,13],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o([5,10,13,16,29,30],[2,12],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,15],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vq,[2,16],{9:$Vb,20:$Vk}),o($Vq,[2,17],{9:$Vb,20:$Vk}),o([5,10,11,13,14,15,16,17,18,19,20,29,30],[2,18],{9:$Vb}),o($Vm,[2,43]),o($Vl,[2,8]),o($Vl,[2,21]),{13:[1,72],29:[1,73],30:[1,74]},o($Vr,[2,38],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,39]),o($Vn,[2,45]),o($Vl,[2,29]),o($Vl,[2,30]),o($Vl,[2,31]),o($Vl,[2,32]),o($Vl,[2,33]),o($Vl,[2,34]),o($Vl,[2,35]),o($Vl,[2,36]),o($Vl,[2,37]),o($Vp,[2,9],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,11],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,10],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vl,[2,22]),{2:11,4:75,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:76,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vr,[2,40],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,41],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk})],
defaultActions: {18:[2,1]},
parseError: function parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
function _parseError (msg, hash) {
this.message = msg;
this.hash = hash;
}
_parseError.prototype = Error;
throw new _parseError(str, hash);
}
},
parse: function parse(input) {
var self = this,
stack = [0],
tstack = [], // token stack
vstack = [null], // semantic value stack
lstack = [], // location stack
table = this.table,
yytext = '',
yylineno = 0,
yyleng = 0,
recovering = 0,
TERROR = 2,
EOF = 1;
var args = lstack.slice.call(arguments, 1);
//this.reductionCount = this.shiftCount = 0;
var lexer = Object.create(this.lexer);
var sharedState = { yy: {} };
// copy state
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function popStack (n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
var lex = function () {
var token;
token = lexer.lex() || EOF;
// if token isn't its numeric value, convert
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
}
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) {
// retreive state number from top of stack
state = stack[stack.length - 1];
// use default actions if available
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
// read action for current state and first input
action = table[state] && table[state][symbol];
}
// handle parse error
if (typeof action === 'undefined' || !action.length || !action[0]) {
var error_rule_depth;
var errStr = '';
// Return the rule stack depth where the nearest error rule can be found.
// Return FALSE when no error recovery rule was found.
function locateNearestErrorRecoveryRule(state) {
var stack_probe = stack.length - 1;
var depth = 0;
// try to recover from error
for(;;) {
// check for error recovery rule in this state
if ((TERROR.toString()) in table[state]) {
return depth;
}
if (state === 0 || stack_probe < 2) {
return false; // No suitable error recovery rule available.
}
stack_probe -= 2; // popStack(1): [symbol, action]
state = stack[stack_probe];
++depth;
}
}
if (!recovering) {
// first see if there's any chance at hitting an error recovery rule:
error_rule_depth = locateNearestErrorRecoveryRule(state);
// Report error
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push("'"+this.terminals_[p]+"'");
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line '+(yylineno+1)+":\n"+lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol)+ "'";
} else {
errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
(symbol == EOF ? "end of input" :
("'"+(this.terminals_[symbol] || symbol)+"'"));
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected,
recoverable: (error_rule_depth !== false)
});
} else if (preErrorSymbol !== EOF) {
error_rule_depth = locateNearestErrorRecoveryRule(state);
}
// just recovered from another error
if (recovering == 3) {
if (symbol === EOF || preErrorSymbol === EOF) {
throw new Error(errStr || 'Parsing halted while starting to recover from another error.');
}
// discard current lookahead and grab another
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
symbol = lex();
}
// try to recover from error
if (error_rule_depth === false) {
throw new Error(errStr || 'Parsing halted. No suitable error recovery rule available.');
}
popStack(error_rule_depth);
preErrorSymbol = (symbol == TERROR ? null : symbol); // save the lookahead token
symbol = TERROR; // insert generic error symbol as new lookahead
state = stack[stack.length-1];
action = table[state] && table[state][TERROR];
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
}
// this shouldn't happen, unless resolve defaults are off
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
}
switch (action[0]) {
case 1: // shift
//this.shiftCount++;
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]); // push state
symbol = null;
if (!preErrorSymbol) { // normal execution/no error
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
} else {
// error just occurred, resume old lookahead f/ before error
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
// reduce
//this.reductionCount++;
len = this.productions_[action[1]][1];
// perform semantic action
yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
// default location, uses first token for firsts, last for lasts
yyval._$ = {
first_line: lstack[lstack.length-(len||1)].first_line,
last_line: lstack[lstack.length-1].last_line,
first_column: lstack[lstack.length-(len||1)].first_column,
last_column: lstack[lstack.length-1].last_column
};
if (ranges) {
yyval._$.range = [lstack[lstack.length-(len||1)].range[0], lstack[lstack.length-1].range[1]];
}
r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));
if (typeof r !== 'undefined') {
return r;
}
// pop off stack
if (len) {
stack = stack.slice(0,-1*len*2);
vstack = vstack.slice(0, -1*len);
lstack = lstack.slice(0, -1*len);
}
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
vstack.push(yyval.$);
lstack.push(yyval._$);
// goto new state = table[STATE][NONTERMINAL]
newState = table[stack[stack.length-2]][stack[stack.length-1]];
stack.push(newState);
break;
case 3:
// accept
return true;
}
}
return true;
}};
/* generated by jison-lex 0.3.4 */
var lexer = (function(){
var lexer = ({
EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput:function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0,0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input:function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput:function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more:function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject:function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less:function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function (match, indexed_rule) {
var token,
lines,
backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token,
match,
tempMatch,
index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex:function lex() {
var r = this.next();
if (r) {
return r;
} else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin(condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState:function popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
} else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState:function pushState(condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize:function stateStackSize() {
return this.conditionStack.length;
},
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 8;
break;
case 2:return 8;
break;
case 3:return 21;
break;
case 4:return 35;
break;
case 5:return 24;
break;
case 6:return 26;
break;
case 7:return 26;
break;
case 8:return 25;
break;
case 9:return 21;
break;
case 10:return 31;
break;
case 11:return 31;
break;
case 12:return 33;
break;
case 13:return 28;
break;
case 14:return 9;
break;
case 15:return ' ';
break;
case 16:return 32;
break;
case 17:return 27;
break;
case 18:return 29;
break;
case 19:return 30;
break;
case 20:return 18;
break;
case 21:return 19;
break;
case 22:return 17;
break;
case 23:return 11;
break;
case 24:return 20;
break;
case 25:return 12;
break;
case 26:return 13;
break;
case 27:return 15;
break;
case 28:return 14;
break;
case 29:return 16;
break;
case 30:return '"';
break;
case 31:return "'";
break;
case 32:return "!";
break;
case 33:return 10;
break;
case 34:return 34;
break;
case 35:return '#';
break;
case 36:return 5;
break;
}
},
rules: [/^(?:\s+)/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9\.]+(?=[(]))/,/^(?:#[A-Z0-9\/]+(!|\?)?)/,/^(?:\$[A-Za-z]+\$[0-9]+)/,/^(?:\$[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z]+\$[0-9]+)/,/^(?:[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z\.]+(?=[(]))/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)/,/^(?:[A-Za-z_]+)/,/^(?:[0-9]+)/,/^(?:\[(.*)?\])/,/^(?:&)/,/^(?: )/,/^(?:[.])/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\/)/,/^(?:-)/,/^(?:\+)/,/^(?:\^)/,/^(?:\()/,/^(?:\))/,/^(?:>)/,/^(?:<)/,/^(?:NOT\b)/,/^(?:")/,/^(?:')/,/^(?:!)/,/^(?:=)/,/^(?:%)/,/^(?:[#])/,/^(?:$)/],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"inclusive":true}}
});
return lexer;
})();
parser.lexer = lexer;
function Parser () {
this.yy = {};
}
Parser.prototype = parser;parser.Parser = Parser;
return new Parser;
})();
@@ -0,0 +1,234 @@
// Provenance: jas-/node-libnmap (fixed).
// repo: jas-/node-libnmap
// commit: c235b24b0342e12a5dbf502f89daabe95883b6c8
// parent: 49b72239b144ab7ffdf673b62e18bfd0760948f6
// commit_url: https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8
// cve: CVE-2018-16461
// license: MIT
// function: block
// relpath: lib/classes/tools.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 20
class tools extends emitter {
/**
* @function merge
* Perform preliminary option/default object merge
*
* @param {Object} defaults Application defaults
* @param {Object} obj User supplied object
*
* @returns {Object}
*/
merge(defaults, obj) {
return merge(defaults, obj);
}
/**
* @function chunk
* Defines new property for array's
*
* @param {Array} obj Supplied array
* @param {Integer} offset Supplied offset
*
* @returns {Array}
*/
chunk(obj, offset) {
let idx = 0;
const alength = obj.length;
const tarray = [];
for (idx = 0; idx < alength; idx += offset) {
tarray.push(obj.slice(idx, idx + offset).join(' '));
}
return tarray;
}
/**
* @function flatten
* Flattens nested arrays into one flat array
*
* @param {Array} arr Array combinator
* @param {Array} obj User supplied array
*
* @returns {Array}
*/
flatten(arr, obj) {
let value;
const result = [];
for (let i = 0, length = arr.length; i < length; i++) {
value = arr[i];
if (Array.isArray(value)) {
return this.flatten(value, obj);
}
else {
result.push(value);
}
}
return result;
}
/**
* @function funcs
* Create functions for use as callbacks
*
* @param {Obect} opts Application defaults
*
* @returns {Array}
*/
funcs(opts) {
const scope = this;
const funcs = {};
let cmd = false;
const errors = [];
const reports = [];
if (opts.range.length <= 0)
return "Range of hosts could not be created";
Object.keys(opts.range).forEach(function blocks(block) {
// Acquire an array of ranges
const range = opts.range[block];
// Create a new function for each range block
funcs[range] = function block(callback) {
const report = [];
// Capture the flags, & ranges as a command string
cmd = scope.command(opts, range);
// Split up cmd for .spawn()
const obj = cmd.split(" ");
cmd = obj[0];
const args = obj.slice(1);
if (opts.verbose)
console.log(`Running: ${cmd}`);
// Push it on to the heap
const execute = proc(cmd, args);
// Discard stderr for now, maybe log?
execute.stderr.on('data', (chunk) => {
/* Silently discard stderr messages to not interupt scans */
});
// Push to array of reports
execute.stdout.on('data', (chunk) => {
report.push(chunk);
});
// Push report array to reporting function on stream end
execute.stdout.on('end', () => {
if (report.length > 0)
return reporting.reports(opts, report, callback);
});
};
});
return funcs;
}
/**
* @function command
* Generate nmap command string
*
* @param {Object} opts - User supplied options
* @param {String} block - Network block
*
* @returns {String} NMAP scan string
*/
command(opts, block) {
const flags = opts.flags.join(' ');
const proto = (opts.udp) ? ' -sU' : ' ';
const to = `--host-timeout=${opts.timeout}s `;
const ipv6 = (validation.test(validation.patterns.IPv6, block)) ?
' -6 ' : ' ';
return (opts.ports) ?
`${opts.nmap+proto} ${to}${flags}${ipv6}-p${opts.ports} ${block}` :
`${opts.nmap+proto} ${to}${flags}${ipv6}${block}`;
}
/**
* @function worker
* Executes object of functions
*
* @param {Object} obj User supplied object
* @param {Function} fn Return function
*/
worker(obj, fn) {
async.parallelLimit(obj.funcs, obj.threshold, fn);
}
/**
* @function init
* @scope private
* Merges supplied options & builds functions
*
* @param {Object} defaults libnmap default options
* @param {Object} opts User supplied configuration object
* @param {Function} cb Callback
*
* @returns {Object}
*/
init(defaults, opts, cb) {
let funcs = [];
const ranges = [];
const called = caller.get()[1].getFunctionName();
/* Override 'defaults.flags' array with 'opts.flags' (prevents merge) */
if (/array/.test(typeof opts.flags))
defaults.flags = opts.flags;
opts = this.merge(defaults, opts);
/* Ensure we can always parse the report */
if (opts.flags.indexOf('-oX -') === -1)
opts.flags.push('-oX -');
/* If we are in a discover mode get adapters for associated network(s) */
if (/nmap.discover/.test(called)) {
/* Bail early if we cannot determine any ranges */
if (!(opts.range = network.adapters(opts)))
return cb(validation.messages.version);
/* Set scan options as static values for 'discover' mode */
opts.ports = '';
opts.flags = [
'-n',
'-oX -',
'-sn',
'-PR'
];
}
validation.init(opts, (err, result) => {
if (err)
return cb(err);
opts.range = network.calculate(opts);
funcs = this.funcs(opts);
return cb(null, {
opts,
funcs
});
});
}
}
@@ -0,0 +1,222 @@
// Provenance: jas-/node-libnmap (vuln).
// repo: jas-/node-libnmap
// commit: 49b72239b144ab7ffdf673b62e18bfd0760948f6
// parent: 49b72239b144ab7ffdf673b62e18bfd0760948f6
// commit_url: https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8
// cve: CVE-2018-16461
// license: MIT
// function: block
// relpath: lib/classes/tools.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 20
class tools extends emitter {
/**
* @function merge
* Perform preliminary option/default object merge
*
* @param {Object} defaults Application defaults
* @param {Object} obj User supplied object
*
* @returns {Object}
*/
merge(defaults, obj) {
return merge(defaults, obj);
}
/**
* @function chunk
* Defines new property for array's
*
* @param {Array} obj Supplied array
* @param {Integer} offset Supplied offset
*
* @returns {Array}
*/
chunk(obj, offset) {
let idx = 0;
const alength = obj.length;
const tarray = [];
for (idx = 0; idx < alength; idx += offset) {
tarray.push(obj.slice(idx, idx + offset).join(' '));
}
return tarray;
}
/**
* @function flatten
* Flattens nested arrays into one flat array
*
* @param {Array} arr Array combinator
* @param {Array} obj User supplied array
*
* @returns {Array}
*/
flatten(arr, obj) {
let value;
const result = [];
for (let i = 0, length = arr.length; i < length; i++) {
value = arr[i];
if (Array.isArray(value)) {
return this.flatten(value, obj);
} else {
result.push(value);
}
}
return result;
}
/**
* @function funcs
* Create functions for use as callbacks
*
* @param {Obect} opts Application defaults
*
* @returns {Array}
*/
funcs(opts) {
const scope = this;
const funcs = {};
let cmd = false;
const errors = [];
const reports = [];
if (opts.range.length <= 0)
return "Range of hosts could not be created";
Object.keys(opts.range).forEach(function blocks(block) {
const range = opts.range[block];
funcs[range] = function block(callback) {
cmd = scope.command(opts, range);
if (opts.verbose)
console.log(`Running: ${cmd}`);
const report = [];
const execute = proc(cmd, (err, stdout, stderr) => {
if (err)
return reporting.reports(opts, err, callback);
});
execute.stderr.on('data', (chunk) => {
/* Silently discard stderr messages to not interupt scans */
});
execute.stdout.on('data', (chunk) => {
report.push(chunk);
});
execute.stdout.on('end', () => {
if (report.length > 0)
return reporting.reports(opts, report, callback);
});
};
});
return funcs;
}
/**
* @function command
* Generate nmap command string
*
* @param {Object} opts - User supplied options
* @param {String} block - Network block
*
* @returns {String} NMAP scan string
*/
command(opts, block) {
const flags = opts.flags.join(' ');
const proto = (opts.udp) ? ' -sU' : ' ';
const to = `--host-timeout=${opts.timeout}s `;
const ipv6 = (validation.test(validation.patterns.IPv6, block)) ?
' -6 ' : ' ';
return (opts.ports) ?
`${opts.nmap+proto} ${to}${flags}${ipv6}-p${opts.ports} ${block}` :
`${opts.nmap+proto} ${to}${flags}${ipv6}${block}`;
}
/**
* @function worker
* Executes object of functions
*
* @param {Object} obj User supplied object
* @param {Function} fn Return function
*/
worker(obj, fn) {
async.parallelLimit(obj.funcs, obj.threshold, fn);
}
/**
* @function init
* @scope private
* Merges supplied options & builds functions
*
* @param {Object} defaults libnmap default options
* @param {Object} opts User supplied configuration object
* @param {Function} cb Callback
*
* @returns {Object}
*/
init(defaults, opts, cb) {
let funcs = [];
const ranges = [];
const called = caller.get()[1].getFunctionName();
/* Override 'defaults.flags' array with 'opts.flags' (prevents merge) */
if (/array/.test(typeof opts.flags))
defaults.flags = opts.flags;
opts = this.merge(defaults, opts);
/* Ensure we can always parse the report */
if (opts.flags.indexOf('-oX -') === -1)
opts.flags.push('-oX -');
/* If we are in a discover mode get adapters for associated network(s) */
if (/nmap.discover/.test(called)) {
/* Bail early if we cannot determine any ranges */
if (!(opts.range = network.adapters(opts)))
return cb(validation.messages.version);
/* Set scan options as static values for 'discover' mode */
opts.ports = '';
opts.flags = [
'-n',
'-oX -',
'-sn',
'-PR'
];
}
validation.init(opts, (err, result) => {
if (err)
return cb(err);
opts.range = network.calculate(opts);
funcs = this.funcs(opts);
return cb(null, {
opts,
funcs
});
});
}
}
@@ -0,0 +1,214 @@
// Provenance: roest01/node-pdf-image (fixed).
// repo: roest01/node-pdf-image
// commit: 54679496a89738443917608c2bbe2f6e5dd20e83
// parent: d8c0dcadd93985dbefe80b84060f5f572bfbb6ff
// commit_url: https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83
// cve: CVE-2018-3757
// license: MIT
// function: getInfo
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 24
PDFImage.prototype = {
constructGetInfoCommand: function () {
return {
cmd: "pdfinfo",
args: [this.pdfFilePath]
};
},
parseGetInfoCommandOutput: function (output) {
var info = {};
output.split("\n").forEach(function (line) {
if (line.match(/^(.*?):[ \t]*(.*)$/)) {
info[RegExp.$1] = RegExp.$2;
}
});
return info;
},
getInfo: function () {
var self = this;
var getInfoCommand = this.constructGetInfoCommand();
return new Promise(function (resolve, reject) {
spawn(getInfoCommand.cmd, getInfoCommand.args, { capture: [ 'stdout', 'stderr' ]})
.then(function (cmdResult) {
resolve(self.parseGetInfoCommandOutput(cmdResult.stdout.toString()));
}).catch(reject);
});
},
numberOfPages: function () {
return this.getInfo().then(function (info) {
return info["Pages"];
});
},
getOutputImagePathForPage: function (pageNumber) {
return path.join(
this.outputDirectory,
this.pdfFileBaseName + "-" + pageNumber + "." + this.convertExtension
);
},
getOutputImagePathForFile: function () {
return path.join(
this.outputDirectory,
this.pdfFileBaseName + "." + this.convertExtension
);
},
setConvertOptions: function (convertOptions) {
this.convertOptions = convertOptions || {};
},
setPdfFileBaseName: function(pdfFileBaseName) {
this.pdfFileBaseName = pdfFileBaseName || path.basename(this.pdfFilePath, ".pdf");
},
setConvertExtension: function (convertExtension) {
this.convertExtension = convertExtension || "png";
},
constructConvertCommandForPage: function (pageNumber) {
var pdfFilePath = this.pdfFilePath;
var outputImagePath = this.getOutputImagePathForPage(pageNumber);
var convertOptions = this.constructConvertOptions();
var args = [];
if (convertOptions) args = convertOptions.slice();
args.push(pdfFilePath+"["+pageNumber+"]");
args.push(outputImagePath);
return {
cmd: this.useGM ? "gm convert" : "convert",
args: args
};
},
constructCombineCommandForFile: function (imagePaths) {
var args = imagePaths.slice();
args.push(this.getOutputImagePathForFile());
args.unshift("-append");
return {
cmd: this.useGM ? "gm convert" : "convert",
args: args
};
},
constructConvertOptions: function () {
var convertOptions = [];
Object.keys(this.convertOptions).sort().map(function (optionName) {
if (this.convertOptions[optionName] !== null) {
convertOptions.push(optionName);
convertOptions.push(this.convertOptions[optionName]);
} else {
convertOptions.push(optionName);
}
}, this);
return convertOptions;
},
combineImages: function(imagePaths) {
var pdfImage = this;
var combineCommand = pdfImage.constructCombineCommandForFile(imagePaths);
return new Promise(function (resolve, reject) {
spawn(combineCommand.cmd, combineCommand.args, { capture: [ 'stdout', 'stderr' ]})
.then(function () {
spawn("rm", imagePaths); //cleanUp
resolve(pdfImage.getOutputImagePathForFile());
}).catch(function(error){
reject({
message: "Failed to combine images",
error: error.message,
stdout: error.stdout,
stderr: error.stderr
});
});
});
},
convertFile: function () {
var pdfImage = this;
return new Promise(function (resolve, reject) {
pdfImage.numberOfPages().then(function (totalPages) {
var convertPromise = new Promise(function (resolve, reject){
var imagePaths = [];
for (var i = 0; i < totalPages; i++) {
pdfImage.convertPage(i).then(function(imagePath){
imagePaths.push(imagePath);
if (imagePaths.length === parseInt(totalPages)){
imagePaths.sort(); //because of asyc pages we have to reSort pages
resolve(imagePaths);
}
}).catch(function(error){
reject(error);
});
}
});
convertPromise.then(function(imagePaths){
if (pdfImage.combinedImage){
pdfImage.combineImages(imagePaths).then(function(imagePath){
resolve(imagePath);
});
} else {
resolve(imagePaths);
}
}).catch(function(error){
reject(error);
});
});
});
},
convertPage: function (pageNumber) {
var pdfFilePath = this.pdfFilePath;
var outputImagePath = this.getOutputImagePathForPage(pageNumber);
var convertCommand = this.constructConvertCommandForPage(pageNumber);
var promise = new Promise(function (resolve, reject) {
function convertPageToImage() {
return new Promise(function (resolve, reject) {
spawn(convertCommand.cmd, convertCommand.args, { capture: [ 'stdout', 'stderr' ]})
.then(function () {
resolve(outputImagePath);
}).catch(function(error){
reject({
message: "Failed to convert page to image",
error: error.message,
stdout: error.stdout,
stderr: error.stderr
});
});
});
}
fs.stat(outputImagePath, function (err, imageFileStat) {
var imageNotExists = err && err.code === "ENOENT";
if (!imageNotExists && err) {
return reject({
message: "Failed to stat image file",
error: err
});
}
// convert when (1) image doesn't exits or (2) image exists
// but its timestamp is older than pdf's one
if (imageNotExists) {
// (1)
convertPageToImage().then(function(result){
resolve(result);
}).catch(reject);
return;
}
// image exist. check timestamp.
fs.stat(pdfFilePath, function (err, pdfFileStat) {
if (err) {
return reject({
message: "Failed to stat PDF file",
error: err
});
}
if (imageFileStat.mtime < pdfFileStat.mtime) {
// (2)
convertPageToImage().then(function(result){
resolve(result);
}).catch(reject);
}
});
});
});
return promise;
}
};
@@ -0,0 +1,212 @@
// Provenance: roest01/node-pdf-image (vuln).
// repo: roest01/node-pdf-image
// commit: d8c0dcadd93985dbefe80b84060f5f572bfbb6ff
// parent: d8c0dcadd93985dbefe80b84060f5f572bfbb6ff
// commit_url: https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83
// cve: CVE-2018-3757
// license: MIT
// function: getInfo
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 24
PDFImage.prototype = {
constructGetInfoCommand: function () {
return util.format(
"pdfinfo \"%s\"",
this.pdfFilePath
);
},
parseGetInfoCommandOutput: function (output) {
var info = {};
output.split("\n").forEach(function (line) {
if (line.match(/^(.*?):[ \t]*(.*)$/)) {
info[RegExp.$1] = RegExp.$2;
}
});
return info;
},
getInfo: function () {
var self = this;
var getInfoCommand = this.constructGetInfoCommand();
var promise = new Promise(function (resolve, reject) {
exec(getInfoCommand, function (err, stdout, stderr) {
if (err) {
return reject({
message: "Failed to get PDF'S information",
error: err,
stdout: stdout,
stderr: stderr
});
}
return resolve(self.parseGetInfoCommandOutput(stdout));
});
});
return promise;
},
numberOfPages: function () {
return this.getInfo().then(function (info) {
return info["Pages"];
});
},
getOutputImagePathForPage: function (pageNumber) {
return path.join(
this.outputDirectory,
this.pdfFileBaseName + "-" + pageNumber + "." + this.convertExtension
);
},
getOutputImagePathForFile: function () {
return path.join(
this.outputDirectory,
this.pdfFileBaseName + "." + this.convertExtension
);
},
setConvertOptions: function (convertOptions) {
this.convertOptions = convertOptions || {};
},
setPdfFileBaseName: function(pdfFileBaseName) {
this.pdfFileBaseName = pdfFileBaseName || path.basename(this.pdfFilePath, ".pdf");
},
setConvertExtension: function (convertExtension) {
this.convertExtension = convertExtension || "png";
},
constructConvertCommandForPage: function (pageNumber) {
var pdfFilePath = this.pdfFilePath;
var outputImagePath = this.getOutputImagePathForPage(pageNumber);
var convertOptionsString = this.constructConvertOptions();
return util.format(
"%s %s\"%s[%d]\" \"%s\"",
this.useGM ? "gm convert" : "convert",
convertOptionsString ? convertOptionsString + " " : "",
pdfFilePath, pageNumber, outputImagePath
);
},
constructCombineCommandForFile: function (imagePaths) {
return util.format(
"%s -append %s \"%s\"",
this.useGM ? "gm convert" : "convert",
imagePaths.join(' '),
this.getOutputImagePathForFile()
);
},
constructConvertOptions: function () {
return Object.keys(this.convertOptions).sort().map(function (optionName) {
if (this.convertOptions[optionName] !== null) {
return optionName + " " + this.convertOptions[optionName];
} else {
return optionName;
}
}, this).join(" ");
},
combineImages: function(imagePaths) {
var pdfImage = this;
var combineCommand = pdfImage.constructCombineCommandForFile(imagePaths);
return new Promise(function (resolve, reject) {
exec(combineCommand, function (err, stdout, stderr) {
if (err) {
return reject({
message: "Failed to combine images",
error: err,
stdout: stdout,
stderr: stderr
});
}
exec("rm "+imagePaths.join(' ')); //cleanUp
return resolve(pdfImage.getOutputImagePathForFile());
});
});
},
convertFile: function () {
var pdfImage = this;
return new Promise(function (resolve, reject) {
pdfImage.numberOfPages().then(function (totalPages) {
var convertPromise = new Promise(function (resolve, reject){
var imagePaths = [];
for (var i = 0; i < totalPages; i++) {
pdfImage.convertPage(i).then(function(imagePath){
imagePaths.push(imagePath);
if (imagePaths.length === parseInt(totalPages)){
imagePaths.sort(); //because of asyc pages we have to reSort pages
resolve(imagePaths);
}
}).catch(function(error){
reject(error);
});
}
});
convertPromise.then(function(imagePaths){
if (pdfImage.combinedImage){
pdfImage.combineImages(imagePaths).then(function(imagePath){
resolve(imagePath);
});
} else {
resolve(imagePaths);
}
}).catch(function(error){
reject(error);
});
});
});
},
convertPage: function (pageNumber) {
var pdfFilePath = this.pdfFilePath;
var outputImagePath = this.getOutputImagePathForPage(pageNumber);
var convertCommand = this.constructConvertCommandForPage(pageNumber);
var promise = new Promise(function (resolve, reject) {
function convertPageToImage() {
exec(convertCommand, function (err, stdout, stderr) {
if (err) {
return reject({
message: "Failed to convert page to image",
error: err,
stdout: stdout,
stderr: stderr
});
}
return resolve(outputImagePath);
});
}
fs.stat(outputImagePath, function (err, imageFileStat) {
var imageNotExists = err && err.code === "ENOENT";
if (!imageNotExists && err) {
return reject({
message: "Failed to stat image file",
error: err
});
}
// convert when (1) image doesn't exits or (2) image exists
// but its timestamp is older than pdf's one
if (imageNotExists) {
// (1)
convertPageToImage();
return;
}
// image exist. check timestamp.
fs.stat(pdfFilePath, function (err, pdfFileStat) {
if (err) {
return reject({
message: "Failed to stat PDF file",
error: err
});
}
if (imageFileStat.mtime < pdfFileStat.mtime) {
// (2)
convertPageToImage();
return;
}
return resolve(outputImagePath);
});
});
});
return promise;
}
};
@@ -0,0 +1,198 @@
// Provenance: soyuka/pidusage (fixed).
// repo: soyuka/pidusage
// commit: b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d
// parent: e3660d8a8e5e61afad9b02af67356a1e239d6bde
// commit_url: https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d
// cve: CVE-2017-16034
// license: MIT
// function: ps
// relpath: lib/stats.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 1
var os = require('os')
var fs = require('fs')
var p = require('path')
var exec = require('child_process').exec
var spawn = require('child_process').spawn
var helpers = require('./helpers')
var format = require('util').format
var stats = {
history: {},
cpu: null, //used to store cpu informations
proc: function(pid, options, done) {
var self = this
if(this.cpu !== null) {
fs.readFile('/proc/uptime', 'utf8', function(err, uptime) {
if(err) {
return done(err, null)
}
if(uptime === undefined) {
console.error("[pidusage] We couldn't find uptime from /proc/uptime")
self.cpu.uptime = os.uptime()
} else {
self.cpu.uptime = uptime.split(' ')[0]
}
return self.proc_calc(pid, options, done)
})
} else {
helpers.cpu(function(err, cpu) {
if(err) {
return done(err, null)
}
self.cpu = cpu
return self.proc_calc(pid, options, done)
})
}
},
proc_calc: function(pid, options, done) {
pid = parseInt(pid, 10)
var history = this.history[pid] ? this.history[pid] : {}
var cpu = this.cpu
var self = this
//Arguments to path.join must be strings
fs.readFile(p.join('/proc', ''+pid, 'stat'), 'utf8', function(err, infos) {
if(err) {
return done(err, null)
}
//https://github.com/arunoda/node-usage/commit/a6ca74ecb8dd452c3c00ed2bde93294d7bb75aa8
//preventing process space in name by removing values before last ) (pid (name) ...)
var index = infos.lastIndexOf(')')
infos = infos.substr(index + 2).split(' ')
//according to http://man7.org/linux/man-pages/man5/proc.5.html (index 0 based - 2)
//In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks
var stat = {
utime: parseFloat(infos[11]),
stime: parseFloat(infos[12]),
cutime: parseFloat(infos[13]),
cstime: parseFloat(infos[14]),
start: parseFloat(infos[19]) / cpu.clock_tick,
rss: parseFloat(infos[21])
}
//http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599
var childrens = options.childrens ? stat.cutime + stat.cstime : 0
var total = stat.stime - (history.stime || 0) + stat.utime - (history.utime || 0) + childrens
total = total / cpu.clock_tick
//time elapsed between calls
var seconds = history.uptime !== undefined ? cpu.uptime - history.uptime : stat.start - cpu.uptime
seconds = Math.abs(seconds)
seconds = seconds === 0 ? 1 : seconds //we sure can't divide through 0
self.history[pid] = stat
self.history[pid].uptime = cpu.uptime
return done(null, {
cpu: (total / seconds) * 100,
memory: stat.rss * cpu.pagesize
})
})
},
/**
* Get pid informations through ps command
* @param {int} pid
* @return {Function} done (err, stat)
* on os x skip headers with pcpu=,rss=
* on linux it could be --no-header
* on solaris 11 can't figure out a way to do this properly so...
*/
ps: function(pid, options, done) {
pid = parseInt(pid, 10)
var cmd = 'ps -o pcpu,rss -p '
if(os.platform() == 'aix')
cmd = 'ps -o pcpu,rssize -p ' //this one could work on other platforms
exec(cmd + pid, function(err, stdout, stderr) {
if(err)
return done(err, null)
stdout = stdout.split(os.EOL)[1]
stdout = stdout.replace(/^\s+/, '').replace(/\s\s+/g, ' ').split(' ')
return done(null, {
cpu: parseFloat(stdout[0].replace(',', '.')),
memory: parseFloat(stdout[1]) * 1024
})
})
},
/**
* This is really in a beta stage
*/
win: function(pid, options, done) {
pid = parseInt(pid, 10)
var history = this.history[pid] ? this.history[pid] : {}
// http://social.msdn.microsoft.com/Forums/en-US/469ec6b7-4727-4773-9dc7-6e3de40e87b8/cpu-usage-in-for-each-active-process-how-is-this-best-determined-and-implemented-in-an?forum=csharplanguage
var args = 'PROCESS ' + pid + ' get workingsetsize,usermodetime,kernelmodetime'
var wmic = spawn('wmic', args.split(' '), {detached: true})
var stdout = ''
var stderr = ''
var self = this
var uptime = os.uptime()
wmic.stdout.on('data', function(d) {
stdout += d.toString()
})
wmic.stderr.on('data', function(d) {
stderr += d.toString()
})
wmic.on('error', function(err) {
console.error('[pidusage] Command "wmic ' + args + '" failed with error %s', err)
})
wmic.on('close', function(code) {
stdout = stdout.trim()
stderr = stderr.trim()
if(!stdout || code !== 0) {
var error = format('%s Wmic errored, please open an issue on https://github.com/soyuka/pidusage with this message.%s', new Date().toString(), os.EOL)
error += format('Command was "wmic %s" %s System informations: %s - release: %s %s - type %s %s', args, os.EOL, os.EOL, os.release(), os.EOL, os.type(), os.EOL)
stderr = error + (stderr ? format('Wmic reported the following error: %s.', stderr) : 'Wmic reported no errors (stderr empty).')
stderr = format('%s%s%sWmic exited with code %d.', os.EOL, stderr, os.EOL, code)
stderr = format('%s%sStdout was %s', stderr, os.EOL, stdout ? stdout : 'empty')
return done(new Error(stderr, null))
}
stdout = stdout.split(os.EOL)[1].replace(/\s\s+/g, ' ').split(' ')
var stats = {
kernelmodetime: parseFloat(stdout[0]),
usermodetime: parseFloat(stdout[1]),
}
var workingsetsize = parseFloat(stdout[2])
//process usage since last call
var total = stats.kernelmodetime - (history.kernelmodetime || 0) + stats.usermodetime - (history.usermodetime || 0)
total = total / 10000000
//time elapsed between calls
var seconds = history.uptime !== undefined ? uptime - history.uptime : 0
seconds = Math.abs(seconds)
seconds = seconds === 0 ? 1 : seconds //we sure can't divide through 0
self.history[pid] = stats
self.history[pid].uptime = uptime
return done(null, {cpu: (total / seconds) * 100, memory: workingsetsize})
})
wmic.stdin.end()
}
}
@@ -0,0 +1,194 @@
// Provenance: soyuka/pidusage (vuln).
// repo: soyuka/pidusage
// commit: e3660d8a8e5e61afad9b02af67356a1e239d6bde
// parent: e3660d8a8e5e61afad9b02af67356a1e239d6bde
// commit_url: https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d
// cve: CVE-2017-16034
// license: MIT
// function: ps
// relpath: lib/stats.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 1
var os = require('os')
var fs = require('fs')
var p = require('path')
var exec = require('child_process').exec
var spawn = require('child_process').spawn
var helpers = require('./helpers')
var format = require('util').format
var stats = {
history: {},
cpu: null, //used to store cpu informations
proc: function(pid, options, done) {
var self = this
if(this.cpu !== null) {
fs.readFile('/proc/uptime', 'utf8', function(err, uptime) {
if(err)
return done(err, null)
if(uptime === undefined) {
console.error("[pidusage] We couldn't find uptime from /proc/uptime")
self.cpu.uptime = os.uptime()
} else {
self.cpu.uptime = uptime.split(' ')[0]
}
return self.proc_calc(pid, options, done)
})
} else {
helpers.cpu(function(err, cpu) {
if(err)
return done(err, null)
self.cpu = cpu
return self.proc_calc(pid, options, done)
})
}
},
proc_calc: function(pid, options, done) {
var history = this.history[pid] ? this.history[pid] : {}
var cpu = this.cpu
var self = this
//Arguments to path.join must be strings
fs.readFile(p.join('/proc', ''+pid, 'stat'), 'utf8', function(err, infos) {
if(err)
return done(err, null)
//https://github.com/arunoda/node-usage/commit/a6ca74ecb8dd452c3c00ed2bde93294d7bb75aa8
//preventing process space in name by removing values before last ) (pid (name) ...)
var index = infos.lastIndexOf(')')
infos = infos.substr(index + 2).split(' ')
//according to http://man7.org/linux/man-pages/man5/proc.5.html (index 0 based - 2)
//In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks
var stat = {
utime: parseFloat(infos[11]),
stime: parseFloat(infos[12]),
cutime: parseFloat(infos[13]),
cstime: parseFloat(infos[14]),
start: parseFloat(infos[19]) / cpu.clock_tick,
rss: parseFloat(infos[21])
}
//http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599
var childrens = options.childrens ? stat.cutime + stat.cstime : 0
var total = stat.stime - (history.stime || 0) + stat.utime - (history.utime || 0) + childrens
total = total / cpu.clock_tick
//time elapsed between calls
var seconds = history.uptime !== undefined ? cpu.uptime - history.uptime : stat.start - cpu.uptime
seconds = Math.abs(seconds)
seconds = seconds === 0 ? 1 : seconds //we sure can't divide through 0
self.history[pid] = stat
self.history[pid].uptime = cpu.uptime
return done(null, {
cpu: (total / seconds) * 100,
memory: stat.rss * cpu.pagesize
})
})
},
/**
* Get pid informations through ps command
* @param {int} pid
* @return {Function} done (err, stat)
* on os x skip headers with pcpu=,rss=
* on linux it could be --no-header
* on solaris 11 can't figure out a way to do this properly so...
*/
ps: function(pid, options, done) {
var cmd = 'ps -o pcpu,rss -p '
if(os.platform() == 'aix')
cmd = 'ps -o pcpu,rssize -p ' //this one could work on other platforms
exec(cmd + pid, function(err, stdout, stderr) {
if(err)
return done(err, null)
stdout = stdout.split(os.EOL)[1]
stdout = stdout.replace(/^\s+/, '').replace(/\s\s+/g, ' ').split(' ')
return done(null, {
cpu: parseFloat(stdout[0].replace(',', '.')),
memory: parseFloat(stdout[1]) * 1024
})
})
},
/**
* This is really in a beta stage
*/
win: function(pid, options, done) {
var history = this.history[pid] ? this.history[pid] : {}
// http://social.msdn.microsoft.com/Forums/en-US/469ec6b7-4727-4773-9dc7-6e3de40e87b8/cpu-usage-in-for-each-active-process-how-is-this-best-determined-and-implemented-in-an?forum=csharplanguage
var args = 'PROCESS ' + pid + ' get workingsetsize,usermodetime,kernelmodetime'
var wmic = spawn('wmic', args.split(' '), {detached: true})
var stdout = ''
var stderr = ''
var self = this
var uptime = os.uptime()
wmic.stdout.on('data', function(d) {
stdout += d.toString()
})
wmic.stderr.on('data', function(d) {
stderr += d.toString()
})
wmic.on('error', function(err) {
console.error('[pidusage] Command "wmic ' + args + '" failed with error %s', err)
})
wmic.on('close', function(code) {
stdout = stdout.trim()
stderr = stderr.trim()
if(!stdout || code !== 0) {
var error = format('%s Wmic errored, please open an issue on https://github.com/soyuka/pidusage with this message.%s', new Date().toString(), os.EOL)
error += format('Command was "wmic %s" %s System informations: %s - release: %s %s - type %s %s', args, os.EOL, os.EOL, os.release(), os.EOL, os.type(), os.EOL)
stderr = error + (stderr ? format('Wmic reported the following error: %s.', stderr) : 'Wmic reported no errors (stderr empty).')
stderr = format('%s%s%sWmic exited with code %d.', os.EOL, stderr, os.EOL, code)
stderr = format('%s%sStdout was %s', stderr, os.EOL, stdout ? stdout : 'empty')
return done(new Error(stderr, null))
}
stdout = stdout.split(os.EOL)[1].replace(/\s\s+/g, ' ').split(' ')
var stats = {
kernelmodetime: parseFloat(stdout[0]),
usermodetime: parseFloat(stdout[1]),
}
var workingsetsize = parseFloat(stdout[2])
//process usage since last call
var total = stats.kernelmodetime - (history.kernelmodetime || 0) + stats.usermodetime - (history.usermodetime || 0)
total = total / 10000000
//time elapsed between calls
var seconds = history.uptime !== undefined ? uptime - history.uptime : 0
seconds = Math.abs(seconds)
seconds = seconds === 0 ? 1 : seconds //we sure can't divide through 0
self.history[pid] = stats
self.history[pid].uptime = uptime
return done(null, {cpu: (total / seconds) * 100, memory: workingsetsize})
})
wmic.stdin.end()
}
}
@@ -0,0 +1,37 @@
// Provenance: rrainn/PortProcesses (fixed).
// repo: rrainn/PortProcesses
// commit: 86811216c9b97b01b5722f879f8c88a7aa4214e1
// parent: fffceb09aff7180afbd0bd172e820404b33c8299
// commit_url: https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1
// cve: CVE-2021-23348
// license: MIT
// function: listProcessesOnPort
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 2
const listProcessesOnPort = module.exports.listProcessesOnPort = async port => {
const portNumber = parseInt(port, 10);
if (Number.isNaN(portNumber)) {
console.error("Must provide number for port.");
return;
}
try {
const result = (await exec(`lsof -i :${portNumber}`)).output.split('\n');
const headers = result.shift().split(' ').filter(item => !!item.trim() && item.trim() !== "").map(item => item.toLowerCase());
return result.filter(item => !!item.trim() && item.trim() !== "").reduce((accumulator, currentValue) => {
accumulator.push(currentValue.split(' ').filter(item => !!item.trim() && item.trim() !== "").reduce((accumulator, currentValue, index) => {
if (index > headers.length - 1) {
accumulator[headers[headers.length - 1]] = (!!accumulator[headers[headers.length - 1]].trim() && accumulator[headers[headers.length - 1]].trim() !== "") ? `${accumulator[headers[headers.length - 1]]} ${currentValue}` : currentValue;
} else {
accumulator[headers[index]] = currentValue;
}
return accumulator;
}, {}));
return accumulator;
}, []);
} catch (e) {
console.error(e);
}
};
@@ -0,0 +1,32 @@
// Provenance: rrainn/PortProcesses (vuln).
// repo: rrainn/PortProcesses
// commit: fffceb09aff7180afbd0bd172e820404b33c8299
// parent: fffceb09aff7180afbd0bd172e820404b33c8299
// commit_url: https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1
// cve: CVE-2021-23348
// license: MIT
// function: listProcessesOnPort
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 2
const listProcessesOnPort = module.exports.listProcessesOnPort = async port => {
try {
const result = (await exec(`lsof -i :${port}`)).output.split('\n');
const headers = result.shift().split(' ').filter(item => !!item.trim() && item.trim() !== "").map(item => item.toLowerCase());
return result.filter(item => !!item.trim() && item.trim() !== "").reduce((accumulator, currentValue) => {
accumulator.push(currentValue.split(' ').filter(item => !!item.trim() && item.trim() !== "").reduce((accumulator, currentValue, index) => {
if (index > headers.length - 1) {
accumulator[headers[headers.length - 1]] = (!!accumulator[headers[headers.length - 1]].trim() && accumulator[headers[headers.length - 1]].trim() !== "") ? `${accumulator[headers[headers.length - 1]]} ${currentValue}` : currentValue;
} else {
accumulator[headers[index]] = currentValue;
}
return accumulator;
}, {}));
return accumulator;
}, []);
} catch (e) {
console.error(e);
}
};
+602
View File
@@ -0,0 +1,602 @@
# vfc-js harvest recipes derived from SecBench.js fixCommit metadata by build_recipes.py.
# Excerpts come from the upstream package repository (its license), never from SecBench.js.
[[recipe]]
name = "angular-http-server-1-0-0"
host = "github"
repo = "simonh1000/angular-http-server"
parent = "d171a771a92e4685b24fb77cb894a7b7b8024c5c"
commit = "8bafc9577161469f5dea01e0b98ea9c525d063e9"
path = "angular-http-server.js"
mode = "hunk"
language = "javascript"
relpath = "angular-http-server.js"
license = "Apache-2.0"
cve = ""
year = 2018
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "angular-http-server"
sink_location = "angular-http-server.js:16:29"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink angular-http-server.js:16:29 fixed upstream in 8bafc9577161"
commit_url = "https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9"
split = "train"
[[recipe]]
name = "apex-publish-static-files-2-0-0"
host = "github"
repo = "vincentmorneau/apex-publish-static-files"
parent = "8d28fe8a9a49e5ff3f61e239293b5646528e2915"
commit = "2209af8f2b65c24aa55ab757e0e05b958c16f063"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2018-16462"
year = 2018
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "apex-publish-static-files"
sink_location = "index.js:54:25"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:54:25 fixed upstream in 2209af8f2b65"
commit_url = "https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063"
split = "holdout"
[[recipe]]
name = "arpping-2-0-0"
host = "github"
repo = "haf-decent/arpping"
parent = "ce9efe8ab7f059ddf45ae4f8f7587689ac3c068c"
commit = "0db06723f8c3c73a5cc0829c667d45cba25ca44d"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = ""
year = 2021
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "arpping"
sink_location = "index.js:120:13"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:120:13 fixed upstream in 0db06723f8c3"
commit_url = "https://github.com/haf-decent/arpping/commit/0db06723f8c3c73a5cc0829c667d45cba25ca44d"
split = "train"
[[recipe]]
name = "bestzip-2-1-6"
host = "github"
repo = "nfriedly/node-bestzip"
parent = "fcea252e52b6078eff6caf5531bd32c53fccb59f"
commit = "45d4a901478c6a8f396c8b959dd6cf8fd3f955b6"
path = "lib/bestzip.js"
mode = "hunk"
language = "javascript"
relpath = "lib/bestzip.js"
license = "MIT"
cve = "CVE-2020-7730"
year = 2020
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "bestzip"
sink_location = "lib/bestzip.js:27:27"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/bestzip.js:27:27 fixed upstream in 45d4a901478c"
commit_url = "https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6"
split = "holdout"
[[recipe]]
name = "clamscan-1-2-0"
host = "github"
repo = "kylefarris/clamscan"
parent = "d474da7b89c0d3397cd681e79c7bcc592bff144b"
commit = "5f557c970817fe8c578ec3f7ad3bcbcef4cf5538"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2020-7613"
year = 2020
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "clamscan"
sink_location = "index.js:495:36"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:495:36 fixed upstream in 5f557c970817"
commit_url = "https://github.com/kylefarris/clamscan/commit/5f557c970817fe8c578ec3f7ad3bcbcef4cf5538"
split = "train"
[[recipe]]
name = "codecov-3-6-4"
host = "github"
repo = "codecov/codecov-node"
parent = "5f6cc62d4f83bf3a75c973868259798814cd231e"
commit = "c0711c656686e902af2cd92d6aecc8074de4d83d"
path = "lib/codecov.js"
mode = "hunk"
language = "javascript"
relpath = "lib/codecov.js"
license = "MIT"
cve = "CVE-2020-15123"
year = 2020
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "codecov"
sink_location = "lib/codecov.js:419:7"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/codecov.js:419:7 fixed upstream in c0711c656686"
commit_url = "https://github.com/codecov/codecov-node/commit/c0711c656686e902af2cd92d6aecc8074de4d83d"
split = "holdout"
[[recipe]]
name = "crud-file-server-0-7-0"
host = "github"
repo = "omphalos/crud-file-server"
parent = "833e7fcc2bc8406b9c76836a51ae173f50c56bf0"
commit = "4fc3b404f718abb789f4ce4272c39c7a138c7a82"
path = "crud-file-server.js"
mode = "hunk"
language = "javascript"
relpath = "crud-file-server.js"
license = "Unlicense"
cve = "CVE-2018-3733"
year = 2018
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "crud-file-server"
sink_location = "crud-file-server.js:170:14"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink crud-file-server.js:170:14 fixed upstream in 4fc3b404f718"
commit_url = "https://github.com/omphalos/crud-file-server/commit/4fc3b404f718abb789f4ce4272c39c7a138c7a82"
split = "train"
[[recipe]]
name = "diskusage-ng-0-2-6"
host = "github"
repo = "iximiuz/node-diskusage-ng"
parent = "53c505506553c83861d1bd67823d6a382d3a5a43"
commit = "48e7e093486b528f0c81ec699573e0e4a431b8d3"
path = "lib/posix.js"
mode = "hunk"
language = "javascript"
relpath = "lib/posix.js"
license = "MIT"
cve = "CVE-2020-7631"
year = 2020
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "diskusage-ng"
sink_location = "lib/posix.js:11:5"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/posix.js:11:5 fixed upstream in 48e7e093486b"
commit_url = "https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3"
split = "holdout"
[[recipe]]
name = "dns-sync-0-1-0"
host = "github"
repo = "skoranga/node-dns-sync"
parent = "b748fe77a87749d95876028eda8e759109be4c73"
commit = "d9abaae384b198db1095735ad9c1c73d7b890a0d"
path = "lib/dns-sync.js"
mode = "hunk"
language = "javascript"
relpath = "lib/dns-sync.js"
license = "MIT"
cve = "CVE-2014-9682"
year = 2014
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "dns-sync"
sink_location = "lib/dns-sync.js:21:26"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/dns-sync.js:21:26 fixed upstream in d9abaae384b1"
commit_url = "https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d"
split = "train"
[[recipe]]
name = "get-npm-package-version-1-0-6"
host = "github"
repo = "hoperyy/get-npm-package-version"
parent = "52797864df09049ea28d65d14620774257a965b0"
commit = "40b1cf31a0607ea66f9e30a0c3af1383b52b2dec"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "ISC"
cve = "CVE-2020-7795"
year = 2021
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "get-npm-package-version"
sink_location = "index.js:16:48"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:16:48 fixed upstream in 40b1cf31a060"
commit_url = "https://github.com/hoperyy/get-npm-package-version/commit/40b1cf31a0607ea66f9e30a0c3af1383b52b2dec"
split = "holdout"
[[recipe]]
name = "glance-3-0-0"
host = "github"
repo = "jarofghosts/glance"
parent = "7e69a5539236386e747fb240ae87ea65ed64bb2c"
commit = "8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2018-3715"
year = 2018
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "glance"
sink_location = "index.js:81:14"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink index.js:81:14 fixed upstream in 8cfd88e44ebd"
commit_url = "https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19"
split = "train"
[[recipe]]
name = "hostr-2-0-0"
host = "github"
repo = "henrytseng/hostr"
parent = "5827ba48fd4a08c26604b97798c57d45fe1cd51e"
commit = "789a00047459fd80b6f0a9701a1378a47fb73ba8"
path = "lib/routes/statics.js"
mode = "hunk"
language = "javascript"
relpath = "lib/routes/statics.js"
license = "MIT"
cve = "CVE-2017-16029"
year = 2016
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "hostr"
sink_location = "lib/routes/static.js:56:27"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink lib/routes/static.js:56:27 fixed upstream in 789a00047459"
commit_url = "https://github.com/henrytseng/hostr/commit/789a00047459fd80b6f0a9701a1378a47fb73ba8"
split = "holdout"
[[recipe]]
name = "hot-formula-parser-3-0-0"
host = "github"
repo = "handsontable/formula-parser"
parent = "944136096f44ff4ffd4ba0bcef30970ca4702fce"
commit = "396b089738d4bf30eb570a4fe6a188affa95cd5e"
path = "src/grammar-parser/grammar-parser.js"
mode = "hunk"
language = "javascript"
relpath = "src/grammar-parser/grammar-parser.js"
license = "MIT"
cve = "CVE-2020-6836"
year = 2019
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "hot-formula-parser"
sink_location = "lib/grammar-parser/grammar-parser.js:258:31"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/grammar-parser/grammar-parser.js:258:31 fixed upstream in 396b089738d4"
commit_url = "https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e"
split = "train"
[[recipe]]
name = "is-my-json-valid-2-20-0"
host = "github"
repo = "mafintosh/is-my-json-valid"
parent = "adf40bd9f22f6c9ee7d4c612c4193a7b835416bc"
commit = "3419563687df463b4ca709a2b46be8e15d6a2b3d"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = ""
year = 2020
cwe = "CWE-94"
class = "code injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "is-my-json-valid"
sink_location = "index.js:172:21"
secbench_class = "code-injection"
evidence = "SecBench.js code-injection sink index.js:172:21 fixed upstream in 3419563687df"
commit_url = "https://github.com/mafintosh/is-my-json-valid/commit/3419563687df463b4ca709a2b46be8e15d6a2b3d"
split = "holdout"
[[recipe]]
name = "libnmap-0-4-11"
host = "github"
repo = "jas-/node-libnmap"
parent = "49b72239b144ab7ffdf673b62e18bfd0760948f6"
commit = "c235b24b0342e12a5dbf502f89daabe95883b6c8"
path = "lib/classes/tools.js"
mode = "hunk"
language = "javascript"
relpath = "lib/classes/tools.js"
license = "MIT"
cve = "CVE-2018-16461"
year = 2018
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "libnmap"
sink_location = "lib/classes/tools.js:114:25"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/classes/tools.js:114:25 fixed upstream in c235b24b0342"
commit_url = "https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8"
split = "train"
[[recipe]]
name = "node-simple-router-0-10-0"
host = "github"
repo = "sandy98/node-simple-router"
parent = "91da4299aee0086cc1e0cc837763578af6f82cea"
commit = "dfdd52e2e80607af433097d940b3834fd96df488"
path = "lib/router.js"
mode = "hunk"
language = "javascript"
relpath = "lib/router.js"
license = "MIT"
cve = "CVE-2017-16083"
year = 2017
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "node-simple-router"
sink_location = "lib/router.js:757:27"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink lib/router.js:757:27 fixed upstream in dfdd52e2e806"
commit_url = "https://github.com/sandy98/node-simple-router/commit/dfdd52e2e80607af433097d940b3834fd96df488"
split = "holdout"
[[recipe]]
name = "pdf-image-1-0-5"
host = "github"
repo = "roest01/node-pdf-image"
parent = "d8c0dcadd93985dbefe80b84060f5f572bfbb6ff"
commit = "54679496a89738443917608c2bbe2f6e5dd20e83"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2018-3757"
year = 2018
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "pdf-image"
sink_location = "index.js:43:7"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:43:7 fixed upstream in 54679496a897"
commit_url = "https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83"
split = "train"
[[recipe]]
name = "pidusage-1-0-0"
host = "github"
repo = "soyuka/pidusage"
parent = "e3660d8a8e5e61afad9b02af67356a1e239d6bde"
commit = "b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d"
path = "lib/stats.js"
mode = "hunk"
language = "javascript"
relpath = "lib/stats.js"
license = "MIT"
cve = "CVE-2017-16034"
year = 2017
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "pidusage"
sink_location = "lib/stats.js:108:5"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink lib/stats.js:108:5 fixed upstream in b70eca15f7ca"
commit_url = "https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d"
split = "holdout"
[[recipe]]
name = "portprocesses-1-0-4"
host = "github"
repo = "rrainn/PortProcesses"
parent = "fffceb09aff7180afbd0bd172e820404b33c8299"
commit = "86811216c9b97b01b5722f879f8c88a7aa4214e1"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2021-23348"
year = 2021
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "portprocesses"
sink_location = "exec.js:5:3"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink exec.js:5:3 fixed upstream in 86811216c9b9"
commit_url = "https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1"
split = "train"
[[recipe]]
name = "serve-here-js-1-1-0"
host = "github"
repo = "ChristoPy/serve-here.js"
parent = "ad077637bf7a9fe0dee3262f011aed19a45ce92c"
commit = "cefb51d03290b6a88dd13143ab2de31b8cf57c39"
path = "source/response.js"
mode = "hunk"
language = "javascript"
relpath = "source/response.js"
license = "MIT"
cve = "CVE-2019-5444"
year = 2019
cwe = "CWE-22"
class = "path traversal"
mechanism = "path_join_user_input"
provenance = "human"
origin = "secbench.js"
project = "serve-here.js"
sink_location = "source/server.js:27:15"
secbench_class = "path-traversal"
evidence = "SecBench.js path-traversal sink source/server.js:27:15 fixed upstream in cefb51d03290"
commit_url = "https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39"
split = "holdout"
[[recipe]]
name = "static-eval-1-1-1"
host = "github"
repo = "browserify/static-eval"
parent = "5bba7905b0e797460b8f6c2e38ff6869146faab3"
commit = "32f8efd072625e267aa7237d2daff35738c50d2a"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = ""
year = 2019
cwe = "CWE-94"
class = "code injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "static-eval"
sink_location = "index.js:118:20"
secbench_class = "code-injection"
evidence = "SecBench.js code-injection sink index.js:118:20 fixed upstream in 32f8efd07262"
commit_url = "https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a"
split = "train"
[[recipe]]
name = "thenify-3-3-0"
host = "github"
repo = "thenables/thenify"
parent = "aa21cfb64f47238c764d258d0faf7366a8487e36"
commit = "0d94a24eb933bc835d568f3009f4d269c4c4c17a"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2020-7677"
year = 2020
cwe = "CWE-94"
class = "code injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "thenify"
sink_location = "index.js:17:10"
secbench_class = "code-injection"
evidence = "SecBench.js code-injection sink index.js:17:10 fixed upstream in 0d94a24eb933"
commit_url = "https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a"
split = "holdout"
[[recipe]]
name = "underscore-1-13-0-0"
host = "github"
repo = "jashkenas/underscore"
parent = "ef646ccbbbd971e82719c83fc69f56a5585b3a01"
commit = "4c73526d43838ad6ab43a6134728776632adeb66"
path = "modules/template.js"
mode = "hunk"
language = "javascript"
relpath = "modules/template.js"
license = "MIT"
cve = "CVE-2021-23358"
year = 2021
cwe = "CWE-94"
class = "code injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "underscore"
sink_location = "modules/template.js:71:14"
secbench_class = "code-injection"
evidence = "SecBench.js code-injection sink modules/template.js:71:14 fixed upstream in 4c73526d4383"
commit_url = "https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66"
split = "train"
[[recipe]]
name = "whereis-0-4-0"
host = "github"
repo = "vvo/node-whereis"
parent = "b8b642b1163baa37f15ed49b4064dcbdb6e1876c"
commit = "0f64e3780235004fb6e43bfd153ea3e0e210ee2b"
path = "index.js"
mode = "hunk"
language = "javascript"
relpath = "index.js"
license = "MIT"
cve = "CVE-2018-3772"
year = 2018
cwe = "CWE-78"
class = "command injection"
mechanism = "source_reaches_sink"
provenance = "human"
origin = "secbench.js"
project = "whereis"
sink_location = "index.js:4:6"
secbench_class = "command-injection"
evidence = "SecBench.js command-injection sink index.js:4:6 fixed upstream in 0f64e3780235"
commit_url = "https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b"
split = "holdout"
@@ -0,0 +1,29 @@
// Provenance: ChristoPy/serve-here.js (fixed).
// repo: ChristoPy/serve-here.js
// commit: cefb51d03290b6a88dd13143ab2de31b8cf57c39
// parent: ad077637bf7a9fe0dee3262f011aed19a45ce92c
// commit_url: https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39
// cve: CVE-2019-5444
// license: MIT
// function: ConfigureFilePath
// relpath: source/response.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 14
module.exports.ConfigureFilePath = (Options, FilePath) => {
const Slash = FilePath.split ("")[FilePath.split ("").length - 1] === "/";
if (FilePath === "/") {
return `${Options.RootFolder}/${Options.IndexFile}`;
} else {
const IsMalicious = HasMaliciousPath(Options, FilePath);
if (IsMalicious) {
return null;
} else {
return (Slash ? `${Options.RootFolder}${FilePath.slice (0, -1)}` : `${Options.RootFolder}${FilePath}`);
}
}
}
@@ -0,0 +1,23 @@
// Provenance: ChristoPy/serve-here.js (vuln).
// repo: ChristoPy/serve-here.js
// commit: ad077637bf7a9fe0dee3262f011aed19a45ce92c
// parent: ad077637bf7a9fe0dee3262f011aed19a45ce92c
// commit_url: https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39
// cve: CVE-2019-5444
// license: MIT
// function: ConfigureFilePath
// relpath: source/response.js
// provenance: human
// mechanism: path_join_user_input
// upstream_start: 5
module.exports.ConfigureFilePath = (Options, FilePath) => {
const Slash = FilePath.split ("")[FilePath.split ("").length - 1] === "/";
switch (FilePath) {
case "/": return `${Options.RootFolder}/${Options.IndexFile}`;
default: return (Slash ? `${Options.RootFolder}${FilePath.slice (0, -1)}` : `${Options.RootFolder}${FilePath}`);
}
}
@@ -0,0 +1,188 @@
// Provenance: browserify/static-eval (fixed).
// repo: browserify/static-eval
// commit: 32f8efd072625e267aa7237d2daff35738c50d2a
// parent: 5bba7905b0e797460b8f6c2e38ff6869146faab3
// commit_url: https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a
// cve:
// license: MIT
// function: walk
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 3
module.exports = function (ast, vars) {
if (!vars) vars = {};
var FAIL = {};
var result = (function walk (node, scopeVars) {
if (node.type === 'Literal') {
return node.value;
}
else if (node.type === 'UnaryExpression'){
var val = walk(node.argument)
if (node.operator === '+') return +val
if (node.operator === '-') return -val
if (node.operator === '~') return ~val
if (node.operator === '!') return !val
return FAIL
}
else if (node.type === 'ArrayExpression') {
var xs = [];
for (var i = 0, l = node.elements.length; i < l; i++) {
var x = walk(node.elements[i]);
if (x === FAIL) return FAIL;
xs.push(x);
}
return xs;
}
else if (node.type === 'ObjectExpression') {
var obj = {};
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
var value = prop.value === null
? prop.value
: walk(prop.value)
;
if (value === FAIL) return FAIL;
obj[prop.key.value || prop.key.name] = value;
}
return obj;
}
else if (node.type === 'BinaryExpression' ||
node.type === 'LogicalExpression') {
var l = walk(node.left);
if (l === FAIL) return FAIL;
var r = walk(node.right);
if (r === FAIL) return FAIL;
var op = node.operator;
if (op === '==') return l == r;
if (op === '===') return l === r;
if (op === '!=') return l != r;
if (op === '!==') return l !== r;
if (op === '+') return l + r;
if (op === '-') return l - r;
if (op === '*') return l * r;
if (op === '/') return l / r;
if (op === '%') return l % r;
if (op === '<') return l < r;
if (op === '<=') return l <= r;
if (op === '>') return l > r;
if (op === '>=') return l >= r;
if (op === '|') return l | r;
if (op === '&') return l & r;
if (op === '^') return l ^ r;
if (op === '&&') return l && r;
if (op === '||') return l || r;
return FAIL;
}
else if (node.type === 'Identifier') {
if ({}.hasOwnProperty.call(vars, node.name)) {
return vars[node.name];
}
else return FAIL;
}
else if (node.type === 'ThisExpression') {
if ({}.hasOwnProperty.call(vars, 'this')) {
return vars['this'];
}
else return FAIL;
}
else if (node.type === 'CallExpression') {
var callee = walk(node.callee);
if (callee === FAIL) return FAIL;
if (typeof callee !== 'function') return FAIL;
var ctx = node.callee.object ? walk(node.callee.object) : FAIL;
if (ctx === FAIL) ctx = null;
var args = [];
for (var i = 0, l = node.arguments.length; i < l; i++) {
var x = walk(node.arguments[i]);
if (x === FAIL) return FAIL;
args.push(x);
}
return callee.apply(ctx, args);
}
else if (node.type === 'MemberExpression') {
var obj = walk(node.object);
// do not allow access to methods on Function
if((obj === FAIL) || (typeof obj == 'function')){
return FAIL;
}
if (node.property.type === 'Identifier') {
return obj[node.property.name];
}
var prop = walk(node.property);
if (prop === FAIL) return FAIL;
return obj[prop];
}
else if (node.type === 'ConditionalExpression') {
var val = walk(node.test)
if (val === FAIL) return FAIL;
return val ? walk(node.consequent) : walk(node.alternate)
}
else if (node.type === 'ExpressionStatement') {
var val = walk(node.expression)
if (val === FAIL) return FAIL;
return val;
}
else if (node.type === 'ReturnStatement') {
return walk(node.argument)
}
else if (node.type === 'FunctionExpression') {
var bodies = node.body.body;
// Create a "scope" for our arguments
var oldVars = {};
Object.keys(vars).forEach(function(element){
oldVars[element] = vars[element];
})
node.params.forEach(function(key) {
if(key.type == 'Identifier'){
vars[key.name] = null;
}
else return FAIL;
});
for(var i in bodies){
if(walk(bodies[i]) === FAIL){
return FAIL;
}
}
// restore the vars and scope after we walk
vars = oldVars;
var keys = Object.keys(vars);
var vals = keys.map(function(key) {
return vars[key];
});
return Function(keys.join(', '), 'return ' + unparse(node)).apply(null, vals);
}
else if (node.type === 'TemplateLiteral') {
var str = '';
for (var i = 0; i < node.expressions.length; i++) {
str += walk(node.quasis[i]);
str += walk(node.expressions[i]);
}
str += walk(node.quasis[i]);
return str;
}
else if (node.type === 'TaggedTemplateExpression') {
var tag = walk(node.tag);
var quasi = node.quasi;
var strings = quasi.quasis.map(walk);
var values = quasi.expressions.map(walk);
return tag.apply(null, [strings].concat(values));
}
else if (node.type === 'TemplateElement') {
return node.value.cooked;
}
else return FAIL;
})(ast);
return result === FAIL ? undefined : result;
};
@@ -0,0 +1,187 @@
// Provenance: browserify/static-eval (vuln).
// repo: browserify/static-eval
// commit: 5bba7905b0e797460b8f6c2e38ff6869146faab3
// parent: 5bba7905b0e797460b8f6c2e38ff6869146faab3
// commit_url: https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a
// cve:
// license: MIT
// function: walk
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 3
module.exports = function (ast, vars) {
if (!vars) vars = {};
var FAIL = {};
var result = (function walk (node, scopeVars) {
if (node.type === 'Literal') {
return node.value;
}
else if (node.type === 'UnaryExpression'){
var val = walk(node.argument)
if (node.operator === '+') return +val
if (node.operator === '-') return -val
if (node.operator === '~') return ~val
if (node.operator === '!') return !val
return FAIL
}
else if (node.type === 'ArrayExpression') {
var xs = [];
for (var i = 0, l = node.elements.length; i < l; i++) {
var x = walk(node.elements[i]);
if (x === FAIL) return FAIL;
xs.push(x);
}
return xs;
}
else if (node.type === 'ObjectExpression') {
var obj = {};
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
var value = prop.value === null
? prop.value
: walk(prop.value)
;
if (value === FAIL) return FAIL;
obj[prop.key.value || prop.key.name] = value;
}
return obj;
}
else if (node.type === 'BinaryExpression' ||
node.type === 'LogicalExpression') {
var l = walk(node.left);
if (l === FAIL) return FAIL;
var r = walk(node.right);
if (r === FAIL) return FAIL;
var op = node.operator;
if (op === '==') return l == r;
if (op === '===') return l === r;
if (op === '!=') return l != r;
if (op === '!==') return l !== r;
if (op === '+') return l + r;
if (op === '-') return l - r;
if (op === '*') return l * r;
if (op === '/') return l / r;
if (op === '%') return l % r;
if (op === '<') return l < r;
if (op === '<=') return l <= r;
if (op === '>') return l > r;
if (op === '>=') return l >= r;
if (op === '|') return l | r;
if (op === '&') return l & r;
if (op === '^') return l ^ r;
if (op === '&&') return l && r;
if (op === '||') return l || r;
return FAIL;
}
else if (node.type === 'Identifier') {
if ({}.hasOwnProperty.call(vars, node.name)) {
return vars[node.name];
}
else return FAIL;
}
else if (node.type === 'ThisExpression') {
if ({}.hasOwnProperty.call(vars, 'this')) {
return vars['this'];
}
else return FAIL;
}
else if (node.type === 'CallExpression') {
var callee = walk(node.callee);
if (callee === FAIL) return FAIL;
if (typeof callee !== 'function') return FAIL;
var ctx = node.callee.object ? walk(node.callee.object) : FAIL;
if (ctx === FAIL) ctx = null;
var args = [];
for (var i = 0, l = node.arguments.length; i < l; i++) {
var x = walk(node.arguments[i]);
if (x === FAIL) return FAIL;
args.push(x);
}
return callee.apply(ctx, args);
}
else if (node.type === 'MemberExpression') {
var obj = walk(node.object);
// do not allow access to methods on Function
if((obj === FAIL) || (typeof obj == 'function')){
return FAIL;
}
if (node.property.type === 'Identifier') {
return obj[node.property.name];
}
var prop = walk(node.property);
if (prop === FAIL) return FAIL;
return obj[prop];
}
else if (node.type === 'ConditionalExpression') {
var val = walk(node.test)
if (val === FAIL) return FAIL;
return val ? walk(node.consequent) : walk(node.alternate)
}
else if (node.type === 'ExpressionStatement') {
var val = walk(node.expression)
if (val === FAIL) return FAIL;
return val;
}
else if (node.type === 'ReturnStatement') {
return walk(node.argument)
}
else if (node.type === 'FunctionExpression') {
var bodies = node.body.body;
// Create a "scope" for our arguments
var oldVars = {};
Object.keys(vars).forEach(function(element){
oldVars[element] = vars[element];
})
node.params.forEach(function(key) {
if(key.type == 'Identifier'){
vars[key.name] = null;
}
});
for(var i in bodies){
if(walk(bodies[i]) === FAIL){
return FAIL;
}
}
// restore the vars and scope after we walk
vars = oldVars;
var keys = Object.keys(vars);
var vals = keys.map(function(key) {
return vars[key];
});
return Function(keys.join(', '), 'return ' + unparse(node)).apply(null, vals);
}
else if (node.type === 'TemplateLiteral') {
var str = '';
for (var i = 0; i < node.expressions.length; i++) {
str += walk(node.quasis[i]);
str += walk(node.expressions[i]);
}
str += walk(node.quasis[i]);
return str;
}
else if (node.type === 'TaggedTemplateExpression') {
var tag = walk(node.tag);
var quasi = node.quasi;
var strings = quasi.quasis.map(walk);
var values = quasi.expressions.map(walk);
return tag.apply(null, [strings].concat(values));
}
else if (node.type === 'TemplateElement') {
return node.value.cooked;
}
else return FAIL;
})(ast);
return result === FAIL ? undefined : result;
};

Some files were not shown because too many files have changed in this diff Show More