CVE-2024-27088 (JavaScript, published 2024-02-26T17:15Z)
Description: value: es5-ext contains ECMAScript 5 extensions. Passing functions with very long names or complex default argument names into `function#copy` or `function#toStringTokens` may cause the script to stall. The vulnerability is patched in v0.10.63.
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/medikoo/es5-ext
Files changed:
function/#/to-string-tokens.js
package.json
test/function/#/to-string-tokens.js
Commit message: fix: Support ES2015+ function definitions in `function#toStringTokens()`

Additionally revert from problematic regex based implementation. Addresses #021


Vulnerable code:
var validFunction = require("../valid-function");
var re1 = /^\s*function[\0-')-\uffff]*\(([\0-(*-\uffff]*)\)\s*\{([\0-\uffff]*)\}\s*$/
  , re2 = /^\s*\(?([\0-'*-\uffff]*)\)?\s*=>\s*(\{?[\0-\uffff]*\}?)\s*$/;
	var str = String(validFunction(this)), data = str.match(re1);
	if (!data) {
		data = str.match(re2);
		if (!data) throw new Error("Unrecognized string format");
		data[1] = data[1].trim();
		if (data[2][0] === "{") data[2] = data[2].trim().slice(1, -1);
	}
	return { args: data[1], body: data[2] };
	a.deep(t.call(function () { Object(); }), { args: "", body: " Object(); " });
		eval("(() => {})");

Fixed code:
var isValue       = require("../../object/is-value")
  , esniff        = require("esniff")
  , validFunction = require("../valid-function");
var classRe = /^\s*class[\s{/}]/;
	var str = String(validFunction(this));
	if (classRe.test(str)) throw new Error("Class methods are not supported");

	var argsStartIndex
	  , argsEndIndex
	  , bodyStartIndex
	  , bodyEndReverseIndex = -1
	  , shouldTrimArgs = false;

	esniff(str, function (emitter, accessor) {
		emitter.once("trigger:(", function () { argsStartIndex = accessor.index + 1; });
		emitter.once("trigger:=", function () {
			if (isValue(argsStartIndex)) return;
			argsStartIndex = 0;
			argsEndIndex = accessor.index;
			shouldTrimArgs = true;
			if (!accessor.skipCodePart("=>")) {
				throw new Error("Unexpected function string: " + str);
			}
			accessor.skipWhitespace();
			if (!accessor.skipCodePart("{")) bodyEndReverseIndex = Infinity;
			bodyStartIndex = accessor.index;
		});
		emitter.on("trigger:)", function () {
			if (accessor.scopeDepth) return;
			argsEndIndex = accessor.index;
			accessor.skipCodePart(")");
			accessor.skipWhitespace();
			if (accessor.skipCodePart("=>")) {
				accessor.skipWhitespace();
				if (!accessor.skipCodePart("{")) bodyEndReverseIndex = Infinity;
			} else if (!accessor.skipCodePart("{")) {
				throw new Error("Unexpected function string: " + str);
			}
			bodyStartIndex = accessor.index;
			accessor.stop();
		});
	});

	var argsString = str.slice(argsStartIndex, argsEndIndex);
	if (shouldTrimArgs) argsString = argsString.trim();
	return { args: argsString, body: str.slice(bodyStartIndex, bodyEndReverseIndex) };
		"esniff": "^2.0.1",
	a.deep(t.call(function () { return {}; }), { args: "", body: " return {}; " });
		eval("((foo = bar) => {})");
	a.deep(t.call(eval("foo=>bar")), { args: "foo", body: "bar" });
	a.deep(t.call(eval("(foo = { marko: (elo) => { someFunct(); } }) => { body(); }")), {
		args: "foo = { marko: (elo) => { someFunct(); } }",
		body: " body(); "
	});