From 6a37610714a8aab8d275de0dfca0045f625be5ca Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 20 Aug 2026 20:29:11 +0100 Subject: [PATCH 1/3] JS: Add 'merge-descriptors' test. --- .../library-tests/Extend/ExtendCalls.expected | 23 ++++++++++--------- .../ql/test/library-tests/Extend/package.json | 1 + .../ql/test/library-tests/Extend/tst.js | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected index a4c66634f7cb..1b4648c9f83c 100644 --- a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected +++ b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected @@ -29,17 +29,18 @@ | tst.js:64:1:64:48 | checkSh ... arg())) | OK | | tst.js:65:1:65:54 | checkSh ... arg())) | OK | | tst.js:66:1:66:45 | checkSh ... arg())) | OK | -| tst.js:67:1:67:52 | checkSh ... arg())) | OK | -| tst.js:68:1:68:53 | checkSh ... arg())) | OK | +| tst.js:67:1:67:57 | checkSh ... arg())) | Not an extend call | +| tst.js:68:1:68:52 | checkSh ... arg())) | OK | | tst.js:69:1:69:53 | checkSh ... arg())) | OK | -| tst.js:70:1:70:55 | checkSh ... arg())) | OK | -| tst.js:71:1:71:52 | checkSh ... arg())) | OK | -| tst.js:72:1:72:51 | checkSh ... arg())) | OK | +| tst.js:70:1:70:53 | checkSh ... arg())) | OK | +| tst.js:71:1:71:55 | checkSh ... arg())) | OK | +| tst.js:72:1:72:52 | checkSh ... arg())) | OK | | tst.js:73:1:73:51 | checkSh ... arg())) | OK | -| tst.js:74:1:74:53 | checkSh ... arg())) | OK | +| tst.js:74:1:74:51 | checkSh ... arg())) | OK | | tst.js:75:1:75:53 | checkSh ... arg())) | OK | -| tst.js:79:1:79:45 | checkSh ... arg())) | OK | -| tst.js:80:1:80:55 | checkSh ... arg())) | OK | -| tst.js:81:1:81:51 | checkSh ... arg())) | OK | -| tst.js:85:1:85:44 | checkDe ... arg())) | OK | -| tst.js:86:1:86:61 | checkDe ... arg())) | OK | +| tst.js:76:1:76:53 | checkSh ... arg())) | OK | +| tst.js:80:1:80:45 | checkSh ... arg())) | OK | +| tst.js:81:1:81:55 | checkSh ... arg())) | OK | +| tst.js:82:1:82:51 | checkSh ... arg())) | OK | +| tst.js:86:1:86:44 | checkDe ... arg())) | OK | +| tst.js:87:1:87:61 | checkDe ... arg())) | OK | diff --git a/javascript/ql/test/library-tests/Extend/package.json b/javascript/ql/test/library-tests/Extend/package.json index dd73e8e0a5ec..c18a62e2c71e 100644 --- a/javascript/ql/test/library-tests/Extend/package.json +++ b/javascript/ql/test/library-tests/Extend/package.json @@ -17,6 +17,7 @@ "lodash.mergewith": "^4.6.1", "merge": "^1.2.0", "merge-deep": "^3.0.2", + "merge-descriptors": "^1.0.3", "merge-options": "^1.0.1", "mixin-deep": "^2.0.0", "mixin-object": "^3.0.0", diff --git a/javascript/ql/test/library-tests/Extend/tst.js b/javascript/ql/test/library-tests/Extend/tst.js index 500178e3e5d3..dc92a2564efc 100644 --- a/javascript/ql/test/library-tests/Extend/tst.js +++ b/javascript/ql/test/library-tests/Extend/tst.js @@ -64,6 +64,7 @@ checkShallow(Object.assign(base(), arg())); checkShallow(require("defaults")(base(), arg())); checkShallow(require("extend-shallow")(base(), arg())); checkShallow(require("merge")(base(), arg())); +checkShallow(require("merge-descriptors")(base(), arg())); checkShallow(require("mixin-object")(base(), arg())); checkShallow(require("object-assign")(base(), arg())); checkShallow(require("object.assign")(base(), arg())); From 77877e047e35cd16e350fea0b6fcd84007c25c3c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 20 Aug 2026 20:31:28 +0100 Subject: [PATCH 2/3] JS: Model 'merge-descriptors' as a shallow extender and accept test changes. --- javascript/ql/lib/semmle/javascript/Extend.qll | 13 +++++++++++++ .../test/library-tests/Extend/ExtendCalls.expected | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Extend.qll b/javascript/ql/lib/semmle/javascript/Extend.qll index b871a74a03b7..436d961aab57 100644 --- a/javascript/ql/lib/semmle/javascript/Extend.qll +++ b/javascript/ql/lib/semmle/javascript/Extend.qll @@ -146,6 +146,19 @@ private class ExtendCallShallow extends ExtendCall { override predicate isDeep() { none() } } +/** A shallow extend call of form `mergeDescriptors(dst, src)`. */ +private class MergeDescriptorsCall extends ExtendCall { + MergeDescriptorsCall() { + this = DataFlow::moduleImport("merge-descriptors").getACall() + } + + override DataFlow::Node getASourceOperand() { result = this.getArgument(1) } + + override DataFlow::Node getDestinationOperand() { result = this.getArgument(0) } + + override predicate isDeep() { none() } +} + /** * A shallow extend call of form `extend(src1, src2, ...)`. */ diff --git a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected index 1b4648c9f83c..f77739770720 100644 --- a/javascript/ql/test/library-tests/Extend/ExtendCalls.expected +++ b/javascript/ql/test/library-tests/Extend/ExtendCalls.expected @@ -29,7 +29,7 @@ | tst.js:64:1:64:48 | checkSh ... arg())) | OK | | tst.js:65:1:65:54 | checkSh ... arg())) | OK | | tst.js:66:1:66:45 | checkSh ... arg())) | OK | -| tst.js:67:1:67:57 | checkSh ... arg())) | Not an extend call | +| tst.js:67:1:67:57 | checkSh ... arg())) | OK | | tst.js:68:1:68:52 | checkSh ... arg())) | OK | | tst.js:69:1:69:53 | checkSh ... arg())) | OK | | tst.js:70:1:70:53 | checkSh ... arg())) | OK | From 58c6e802bc8cb120655eec2fd1779fe9e99de069 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 21 Aug 2026 10:35:36 +0100 Subject: [PATCH 3/3] JS: Autoformat. --- javascript/ql/lib/semmle/javascript/Extend.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Extend.qll b/javascript/ql/lib/semmle/javascript/Extend.qll index 436d961aab57..d592929dc0ec 100644 --- a/javascript/ql/lib/semmle/javascript/Extend.qll +++ b/javascript/ql/lib/semmle/javascript/Extend.qll @@ -148,9 +148,7 @@ private class ExtendCallShallow extends ExtendCall { /** A shallow extend call of form `mergeDescriptors(dst, src)`. */ private class MergeDescriptorsCall extends ExtendCall { - MergeDescriptorsCall() { - this = DataFlow::moduleImport("merge-descriptors").getACall() - } + MergeDescriptorsCall() { this = DataFlow::moduleImport("merge-descriptors").getACall() } override DataFlow::Node getASourceOperand() { result = this.getArgument(1) }