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
+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;
};
@@ -0,0 +1,30 @@
// Provenance: thenables/thenify (fixed).
// repo: thenables/thenify
// commit: 0d94a24eb933bc835d568f3009f4d269c4c4c17a
// parent: aa21cfb64f47238c764d258d0faf7366a8487e36
// commit_url: https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a
// cve: CVE-2020-7677
// license: MIT
// function: thenify
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 2
var Promise = require('any-promise')
var assert = require('assert')
module.exports = thenify
/**
* Turn async functions into promises
*
* @param {Function} fn
* @return {Function}
* @api public
*/
function thenify(fn, options) {
assert(typeof fn === 'function')
return createWrapper(fn, options)
}
@@ -0,0 +1,30 @@
// Provenance: thenables/thenify (vuln).
// repo: thenables/thenify
// commit: aa21cfb64f47238c764d258d0faf7366a8487e36
// parent: aa21cfb64f47238c764d258d0faf7366a8487e36
// commit_url: https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a
// cve: CVE-2020-7677
// license: MIT
// function: thenify
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 2
var Promise = require('any-promise')
var assert = require('assert')
module.exports = thenify
/**
* Turn async functions into promises
*
* @param {Function} $$__fn__$$
* @return {Function}
* @api public
*/
function thenify($$__fn__$$, options) {
assert(typeof $$__fn__$$ === 'function')
return eval(createWrapper($$__fn__$$.name, options))
}
@@ -0,0 +1,34 @@
{"class": "path traversal", "commit": "d171a771a92e4685b24fb77cb894a7b7b8024c5c", "commit_url": "https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9", "cve": "", "cwe": "CWE-22", "file": "angular-http-server-1-0-0/vuln.js", "function": "requestListener", "id": "angular-http-server-1-0-0:vuln", "label": "vuln", "license": "Apache-2.0", "mechanism": "path_join_user_input", "pair": "angular-http-server-1-0-0", "project": "angular-http-server", "provenance": "human", "relpath": "angular-http-server.js", "repo": "simonh1000/angular-http-server", "split": "train", "year": 2018}
{"class": "path traversal", "commit": "8bafc9577161469f5dea01e0b98ea9c525d063e9", "commit_url": "https://github.com/simonh1000/angular-http-server/commit/8bafc9577161469f5dea01e0b98ea9c525d063e9", "cve": "", "cwe": "CWE-22", "file": "angular-http-server-1-0-0/fixed.js", "function": "requestListener", "id": "angular-http-server-1-0-0:fixed", "label": "fixed", "license": "Apache-2.0", "mechanism": "path_join_user_input", "pair": "angular-http-server-1-0-0", "project": "angular-http-server", "provenance": "human", "relpath": "angular-http-server.js", "repo": "simonh1000/angular-http-server", "split": "train", "year": 2018}
{"class": "command injection", "commit": "8d28fe8a9a49e5ff3f61e239293b5646528e2915", "commit_url": "https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063", "cve": "CVE-2018-16462", "cwe": "CWE-78", "file": "apex-publish-static-files-2-0-0/vuln.js", "function": "publish", "id": "apex-publish-static-files-2-0-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "apex-publish-static-files-2-0-0", "project": "apex-publish-static-files", "provenance": "human", "relpath": "index.js", "repo": "vincentmorneau/apex-publish-static-files", "split": "holdout", "year": 2018}
{"class": "command injection", "commit": "2209af8f2b65c24aa55ab757e0e05b958c16f063", "commit_url": "https://github.com/vincentmorneau/apex-publish-static-files/commit/2209af8f2b65c24aa55ab757e0e05b958c16f063", "cve": "CVE-2018-16462", "cwe": "CWE-78", "file": "apex-publish-static-files-2-0-0/fixed.js", "function": "publish", "id": "apex-publish-static-files-2-0-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "apex-publish-static-files-2-0-0", "project": "apex-publish-static-files", "provenance": "human", "relpath": "index.js", "repo": "vincentmorneau/apex-publish-static-files", "split": "holdout", "year": 2018}
{"class": "command injection", "commit": "fcea252e52b6078eff6caf5531bd32c53fccb59f", "commit_url": "https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6", "cve": "CVE-2020-7730", "cwe": "CWE-78", "file": "bestzip-2-1-6/vuln.js", "function": "nativeZip", "id": "bestzip-2-1-6:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "bestzip-2-1-6", "project": "bestzip", "provenance": "human", "relpath": "lib/bestzip.js", "repo": "nfriedly/node-bestzip", "split": "holdout", "year": 2020}
{"class": "command injection", "commit": "45d4a901478c6a8f396c8b959dd6cf8fd3f955b6", "commit_url": "https://github.com/nfriedly/node-bestzip/commit/45d4a901478c6a8f396c8b959dd6cf8fd3f955b6", "cve": "CVE-2020-7730", "cwe": "CWE-78", "file": "bestzip-2-1-6/fixed.js", "function": "nativeZip", "id": "bestzip-2-1-6:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "bestzip-2-1-6", "project": "bestzip", "provenance": "human", "relpath": "lib/bestzip.js", "repo": "nfriedly/node-bestzip", "split": "holdout", "year": 2020}
{"class": "command injection", "commit": "d474da7b89c0d3397cd681e79c7bcc592bff144b", "commit_url": "https://github.com/kylefarris/clamscan/commit/5f557c970817fe8c578ec3f7ad3bcbcef4cf5538", "cve": "CVE-2020-7613", "cwe": "CWE-78", "file": "clamscan-1-2-0/vuln.js", "function": "local_scan", "id": "clamscan-1-2-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "clamscan-1-2-0", "project": "clamscan", "provenance": "human", "relpath": "index.js", "repo": "kylefarris/clamscan", "split": "train", "year": 2020}
{"class": "command injection", "commit": "5f557c970817fe8c578ec3f7ad3bcbcef4cf5538", "commit_url": "https://github.com/kylefarris/clamscan/commit/5f557c970817fe8c578ec3f7ad3bcbcef4cf5538", "cve": "CVE-2020-7613", "cwe": "CWE-78", "file": "clamscan-1-2-0/fixed.js", "function": "local_scan", "id": "clamscan-1-2-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "clamscan-1-2-0", "project": "clamscan", "provenance": "human", "relpath": "index.js", "repo": "kylefarris/clamscan", "split": "train", "year": 2020}
{"class": "command injection", "commit": "53c505506553c83861d1bd67823d6a382d3a5a43", "commit_url": "https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3", "cve": "CVE-2020-7631", "cwe": "CWE-78", "file": "diskusage-ng-0-2-6/vuln.js", "function": "diskusage", "id": "diskusage-ng-0-2-6:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "diskusage-ng-0-2-6", "project": "diskusage-ng", "provenance": "human", "relpath": "lib/posix.js", "repo": "iximiuz/node-diskusage-ng", "split": "holdout", "year": 2020}
{"class": "command injection", "commit": "48e7e093486b528f0c81ec699573e0e4a431b8d3", "commit_url": "https://github.com/iximiuz/node-diskusage-ng/commit/48e7e093486b528f0c81ec699573e0e4a431b8d3", "cve": "CVE-2020-7631", "cwe": "CWE-78", "file": "diskusage-ng-0-2-6/fixed.js", "function": "diskusage", "id": "diskusage-ng-0-2-6:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "diskusage-ng-0-2-6", "project": "diskusage-ng", "provenance": "human", "relpath": "lib/posix.js", "repo": "iximiuz/node-diskusage-ng", "split": "holdout", "year": 2020}
{"class": "command injection", "commit": "b748fe77a87749d95876028eda8e759109be4c73", "commit_url": "https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d", "cve": "CVE-2014-9682", "cwe": "CWE-78", "file": "dns-sync-0-1-0/vuln.js", "function": "resolve", "id": "dns-sync-0-1-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dns-sync-0-1-0", "project": "dns-sync", "provenance": "human", "relpath": "lib/dns-sync.js", "repo": "skoranga/node-dns-sync", "split": "train", "year": 2014}
{"class": "command injection", "commit": "d9abaae384b198db1095735ad9c1c73d7b890a0d", "commit_url": "https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d", "cve": "CVE-2014-9682", "cwe": "CWE-78", "file": "dns-sync-0-1-0/fixed.js", "function": "resolve", "id": "dns-sync-0-1-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "dns-sync-0-1-0", "project": "dns-sync", "provenance": "human", "relpath": "lib/dns-sync.js", "repo": "skoranga/node-dns-sync", "split": "train", "year": 2014}
{"class": "path traversal", "commit": "7e69a5539236386e747fb240ae87ea65ed64bb2c", "commit_url": "https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19", "cve": "CVE-2018-3715", "cwe": "CWE-22", "file": "glance-3-0-0/vuln.js", "function": "Glance$serveRequest", "id": "glance-3-0-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "path_join_user_input", "pair": "glance-3-0-0", "project": "glance", "provenance": "human", "relpath": "index.js", "repo": "jarofghosts/glance", "split": "train", "year": 2018}
{"class": "path traversal", "commit": "8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19", "commit_url": "https://github.com/jarofghosts/glance/commit/8cfd88e44ebd3f07e3a2eaf376a3e758b6c4ca19", "cve": "CVE-2018-3715", "cwe": "CWE-22", "file": "glance-3-0-0/fixed.js", "function": "Glance$serveRequest", "id": "glance-3-0-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "path_join_user_input", "pair": "glance-3-0-0", "project": "glance", "provenance": "human", "relpath": "index.js", "repo": "jarofghosts/glance", "split": "train", "year": 2018}
{"class": "command injection", "commit": "944136096f44ff4ffd4ba0bcef30970ca4702fce", "commit_url": "https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e", "cve": "CVE-2020-6836", "cwe": "CWE-78", "file": "hot-formula-parser-3-0-0/vuln.js", "function": "performAction", "id": "hot-formula-parser-3-0-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "hot-formula-parser-3-0-0", "project": "hot-formula-parser", "provenance": "human", "relpath": "src/grammar-parser/grammar-parser.js", "repo": "handsontable/formula-parser", "split": "train", "year": 2019}
{"class": "command injection", "commit": "396b089738d4bf30eb570a4fe6a188affa95cd5e", "commit_url": "https://github.com/handsontable/formula-parser/commit/396b089738d4bf30eb570a4fe6a188affa95cd5e", "cve": "CVE-2020-6836", "cwe": "CWE-78", "file": "hot-formula-parser-3-0-0/fixed.js", "function": "performAction", "id": "hot-formula-parser-3-0-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "hot-formula-parser-3-0-0", "project": "hot-formula-parser", "provenance": "human", "relpath": "src/grammar-parser/grammar-parser.js", "repo": "handsontable/formula-parser", "split": "train", "year": 2019}
{"class": "command injection", "commit": "49b72239b144ab7ffdf673b62e18bfd0760948f6", "commit_url": "https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8", "cve": "CVE-2018-16461", "cwe": "CWE-78", "file": "libnmap-0-4-11/vuln.js", "function": "block", "id": "libnmap-0-4-11:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "libnmap-0-4-11", "project": "libnmap", "provenance": "human", "relpath": "lib/classes/tools.js", "repo": "jas-/node-libnmap", "split": "train", "year": 2018}
{"class": "command injection", "commit": "c235b24b0342e12a5dbf502f89daabe95883b6c8", "commit_url": "https://github.com/jas-/node-libnmap/commit/c235b24b0342e12a5dbf502f89daabe95883b6c8", "cve": "CVE-2018-16461", "cwe": "CWE-78", "file": "libnmap-0-4-11/fixed.js", "function": "block", "id": "libnmap-0-4-11:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "libnmap-0-4-11", "project": "libnmap", "provenance": "human", "relpath": "lib/classes/tools.js", "repo": "jas-/node-libnmap", "split": "train", "year": 2018}
{"class": "command injection", "commit": "d8c0dcadd93985dbefe80b84060f5f572bfbb6ff", "commit_url": "https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83", "cve": "CVE-2018-3757", "cwe": "CWE-78", "file": "pdf-image-1-0-5/vuln.js", "function": "getInfo", "id": "pdf-image-1-0-5:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pdf-image-1-0-5", "project": "pdf-image", "provenance": "human", "relpath": "index.js", "repo": "roest01/node-pdf-image", "split": "train", "year": 2018}
{"class": "command injection", "commit": "54679496a89738443917608c2bbe2f6e5dd20e83", "commit_url": "https://github.com/roest01/node-pdf-image/commit/54679496a89738443917608c2bbe2f6e5dd20e83", "cve": "CVE-2018-3757", "cwe": "CWE-78", "file": "pdf-image-1-0-5/fixed.js", "function": "getInfo", "id": "pdf-image-1-0-5:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pdf-image-1-0-5", "project": "pdf-image", "provenance": "human", "relpath": "index.js", "repo": "roest01/node-pdf-image", "split": "train", "year": 2018}
{"class": "command injection", "commit": "e3660d8a8e5e61afad9b02af67356a1e239d6bde", "commit_url": "https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d", "cve": "CVE-2017-16034", "cwe": "CWE-78", "file": "pidusage-1-0-0/vuln.js", "function": "ps", "id": "pidusage-1-0-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pidusage-1-0-0", "project": "pidusage", "provenance": "human", "relpath": "lib/stats.js", "repo": "soyuka/pidusage", "split": "holdout", "year": 2017}
{"class": "command injection", "commit": "b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d", "commit_url": "https://github.com/soyuka/pidusage/commit/b70eca15f7ca7f1b82a15f8a5d4bb48737f5a89d", "cve": "CVE-2017-16034", "cwe": "CWE-78", "file": "pidusage-1-0-0/fixed.js", "function": "ps", "id": "pidusage-1-0-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "pidusage-1-0-0", "project": "pidusage", "provenance": "human", "relpath": "lib/stats.js", "repo": "soyuka/pidusage", "split": "holdout", "year": 2017}
{"class": "command injection", "commit": "fffceb09aff7180afbd0bd172e820404b33c8299", "commit_url": "https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1", "cve": "CVE-2021-23348", "cwe": "CWE-78", "file": "portprocesses-1-0-4/vuln.js", "function": "listProcessesOnPort", "id": "portprocesses-1-0-4:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "portprocesses-1-0-4", "project": "portprocesses", "provenance": "human", "relpath": "index.js", "repo": "rrainn/PortProcesses", "split": "train", "year": 2021}
{"class": "command injection", "commit": "86811216c9b97b01b5722f879f8c88a7aa4214e1", "commit_url": "https://github.com/rrainn/PortProcesses/commit/86811216c9b97b01b5722f879f8c88a7aa4214e1", "cve": "CVE-2021-23348", "cwe": "CWE-78", "file": "portprocesses-1-0-4/fixed.js", "function": "listProcessesOnPort", "id": "portprocesses-1-0-4:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "portprocesses-1-0-4", "project": "portprocesses", "provenance": "human", "relpath": "index.js", "repo": "rrainn/PortProcesses", "split": "train", "year": 2021}
{"class": "path traversal", "commit": "ad077637bf7a9fe0dee3262f011aed19a45ce92c", "commit_url": "https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39", "cve": "CVE-2019-5444", "cwe": "CWE-22", "file": "serve-here-js-1-1-0/vuln.js", "function": "ConfigureFilePath", "id": "serve-here-js-1-1-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "path_join_user_input", "pair": "serve-here-js-1-1-0", "project": "serve-here.js", "provenance": "human", "relpath": "source/response.js", "repo": "ChristoPy/serve-here.js", "split": "holdout", "year": 2019}
{"class": "path traversal", "commit": "cefb51d03290b6a88dd13143ab2de31b8cf57c39", "commit_url": "https://github.com/ChristoPy/serve-here.js/commit/cefb51d03290b6a88dd13143ab2de31b8cf57c39", "cve": "CVE-2019-5444", "cwe": "CWE-22", "file": "serve-here-js-1-1-0/fixed.js", "function": "ConfigureFilePath", "id": "serve-here-js-1-1-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "path_join_user_input", "pair": "serve-here-js-1-1-0", "project": "serve-here.js", "provenance": "human", "relpath": "source/response.js", "repo": "ChristoPy/serve-here.js", "split": "holdout", "year": 2019}
{"class": "code injection", "commit": "5bba7905b0e797460b8f6c2e38ff6869146faab3", "commit_url": "https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a", "cve": "", "cwe": "CWE-94", "file": "static-eval-1-1-1/vuln.js", "function": "walk", "id": "static-eval-1-1-1:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "static-eval-1-1-1", "project": "static-eval", "provenance": "human", "relpath": "index.js", "repo": "browserify/static-eval", "split": "train", "year": 2019}
{"class": "code injection", "commit": "32f8efd072625e267aa7237d2daff35738c50d2a", "commit_url": "https://github.com/browserify/static-eval/commit/32f8efd072625e267aa7237d2daff35738c50d2a", "cve": "", "cwe": "CWE-94", "file": "static-eval-1-1-1/fixed.js", "function": "walk", "id": "static-eval-1-1-1:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "static-eval-1-1-1", "project": "static-eval", "provenance": "human", "relpath": "index.js", "repo": "browserify/static-eval", "split": "train", "year": 2019}
{"class": "code injection", "commit": "aa21cfb64f47238c764d258d0faf7366a8487e36", "commit_url": "https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a", "cve": "CVE-2020-7677", "cwe": "CWE-94", "file": "thenify-3-3-0/vuln.js", "function": "thenify", "id": "thenify-3-3-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "thenify-3-3-0", "project": "thenify", "provenance": "human", "relpath": "index.js", "repo": "thenables/thenify", "split": "holdout", "year": 2020}
{"class": "code injection", "commit": "0d94a24eb933bc835d568f3009f4d269c4c4c17a", "commit_url": "https://github.com/thenables/thenify/commit/0d94a24eb933bc835d568f3009f4d269c4c4c17a", "cve": "CVE-2020-7677", "cwe": "CWE-94", "file": "thenify-3-3-0/fixed.js", "function": "thenify", "id": "thenify-3-3-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "thenify-3-3-0", "project": "thenify", "provenance": "human", "relpath": "index.js", "repo": "thenables/thenify", "split": "holdout", "year": 2020}
{"class": "code injection", "commit": "ef646ccbbbd971e82719c83fc69f56a5585b3a01", "commit_url": "https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66", "cve": "CVE-2021-23358", "cwe": "CWE-94", "file": "underscore-1-13-0-0/vuln.js", "function": "template", "id": "underscore-1-13-0-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "underscore-1-13-0-0", "project": "underscore", "provenance": "human", "relpath": "modules/template.js", "repo": "jashkenas/underscore", "split": "train", "year": 2021}
{"class": "code injection", "commit": "4c73526d43838ad6ab43a6134728776632adeb66", "commit_url": "https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66", "cve": "CVE-2021-23358", "cwe": "CWE-94", "file": "underscore-1-13-0-0/fixed.js", "function": "template", "id": "underscore-1-13-0-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "underscore-1-13-0-0", "project": "underscore", "provenance": "human", "relpath": "modules/template.js", "repo": "jashkenas/underscore", "split": "train", "year": 2021}
{"class": "command injection", "commit": "b8b642b1163baa37f15ed49b4064dcbdb6e1876c", "commit_url": "https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b", "cve": "CVE-2018-3772", "cwe": "CWE-78", "file": "whereis-0-4-0/vuln.js", "function": "whereis", "id": "whereis-0-4-0:vuln", "label": "vuln", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "whereis-0-4-0", "project": "whereis", "provenance": "human", "relpath": "index.js", "repo": "vvo/node-whereis", "split": "holdout", "year": 2018}
{"class": "command injection", "commit": "0f64e3780235004fb6e43bfd153ea3e0e210ee2b", "commit_url": "https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b", "cve": "CVE-2018-3772", "cwe": "CWE-78", "file": "whereis-0-4-0/fixed.js", "function": "whereis", "id": "whereis-0-4-0:fixed", "label": "fixed", "license": "MIT", "mechanism": "source_reaches_sink", "pair": "whereis-0-4-0", "project": "whereis", "provenance": "human", "relpath": "index.js", "repo": "vvo/node-whereis", "split": "holdout", "year": 2018}
@@ -0,0 +1,77 @@
// Provenance: jashkenas/underscore (fixed).
// repo: jashkenas/underscore
// commit: 4c73526d43838ad6ab43a6134728776632adeb66
// parent: ef646ccbbbd971e82719c83fc69f56a5585b3a01
// commit_url: https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66
// cve: CVE-2021-23358
// license: MIT
// function: template
// relpath: modules/template.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 38
export default function template(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
// Adobe VMs need the match returned to produce the correct offset.
return match;
});
source += "';\n";
var argument = settings.variable;
if (argument) {
// Insure against third-party code injection.
if (!bareIdentifier.test(argument)) throw new Error(
'variable is not a bare identifier: ' + argument
);
} else {
// If a variable is not specified, place data values in local scope.
source = 'with(obj||{}){\n' + source + '}\n';
argument = 'obj';
}
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
var render;
try {
render = new Function(argument, '_', source);
} catch (e) {
e.source = source;
throw e;
}
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled source as a convenience for precompilation.
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
}
@@ -0,0 +1,69 @@
// Provenance: jashkenas/underscore (vuln).
// repo: jashkenas/underscore
// commit: ef646ccbbbd971e82719c83fc69f56a5585b3a01
// parent: ef646ccbbbd971e82719c83fc69f56a5585b3a01
// commit_url: https://github.com/jashkenas/underscore/commit/4c73526d43838ad6ab43a6134728776632adeb66
// cve: CVE-2021-23358
// license: MIT
// function: template
// relpath: modules/template.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 31
export default function template(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
// Adobe VMs need the match returned to produce the correct offset.
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
var render;
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
}
@@ -0,0 +1,42 @@
// Provenance: vvo/node-whereis (fixed).
// repo: vvo/node-whereis
// commit: 0f64e3780235004fb6e43bfd153ea3e0e210ee2b
// parent: b8b642b1163baa37f15ed49b4064dcbdb6e1876c
// commit_url: https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b
// cve: CVE-2018-3772
// license: MIT
// function: whereis
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 3
module.exports = function whereis(name, cb) {
cp.execFile('which', [name], function(error, stdout, stderr) {
stdout = stdout.split('\n')[0];
if (error || stderr || stdout === '' || stdout.charAt(0) !== '/') {
stdout = stdout.split('\n')[0];
cp.execFile('whereis', [name], function(error, stdout, stderr) {
if (error || stderr || stdout === '' || stdout.indexOf( '/' ) === -1) {
cp.execFile('where', [name], function (error, stdout, stderr) { //windows
if (error || stderr || stdout === '' || stdout.indexOf('\\') === -1) {
cp.exec('for %i in (' + name + '.exe) do @echo. %~$PATH:i', function (error, stdout, stderr) { //windows xp
if (error || stderr || stdout === '' || stdout.indexOf('\\') === -1) {
return cb(new Error('Could not find ' + name + ' on your system'));
}
return cb(null, stdout);
});
} else {
return cb(null, stdout);
}
});
}
else {
return cb(null, stdout.split(' ')[1]);
}
});
} else {
return cb(null, stdout);
}
});
};
@@ -0,0 +1,42 @@
// Provenance: vvo/node-whereis (vuln).
// repo: vvo/node-whereis
// commit: b8b642b1163baa37f15ed49b4064dcbdb6e1876c
// parent: b8b642b1163baa37f15ed49b4064dcbdb6e1876c
// commit_url: https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b
// cve: CVE-2018-3772
// license: MIT
// function: whereis
// relpath: index.js
// provenance: human
// mechanism: source_reaches_sink
// upstream_start: 3
module.exports = function whereis(name, cb) {
cp.exec('which ' + name, function(error, stdout, stderr) {
stdout = stdout.split('\n')[0];
if (error || stderr || stdout === '' || stdout.charAt(0) !== '/') {
stdout = stdout.split('\n')[0];
cp.exec('whereis ' + name, function(error, stdout, stderr) {
if (error || stderr || stdout === '' || stdout.indexOf( '/' ) === -1) {
cp.exec('where ' + name, function (error, stdout, stderr) { //windows
if (error || stderr || stdout === '' || stdout.indexOf('\\') === -1) {
cp.exec('for %i in (' + name + '.exe) do @echo. %~$PATH:i', function (error, stdout, stderr) { //windows xp
if (error || stderr || stdout === '' || stdout.indexOf('\\') === -1) {
return cb(new Error('Could not find ' + name + ' on your system'));
}
return cb(null, stdout);
});
} else {
return cb(null, stdout);
}
});
}
else {
return cb(null, stdout.split(' ')[1]);
}
});
} else {
return cb(null, stdout);
}
});
};