Merge remote-tracking branch 'upstream/main' into igfoo/mb

This commit is contained in:
Ian Lynagh
2026-01-13 01:01:35 +00:00
1891 changed files with 180230 additions and 116717 deletions

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `PreCallGraphStep` flow model for React's `useRef` hook.
* Added a `DomValueSource` that uses the `current` property off the object returned by React's `useRef` hook.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
- Support `use cache` directives for Next.js 16.

View File

@@ -434,6 +434,21 @@ module Directive {
class UseClientDirective extends KnownDirective {
UseClientDirective() { this.getDirectiveText() = "use client" }
}
/**
* A `use cache` directive.
*
* Examples:
*
* ```
* "use cache";
* "use cache: remote";
* "use cache: private";
* ```
*/
class UseCacheDirective extends KnownDirective {
UseCacheDirective() { this.getDirectiveText().regexpMatch("use cache(:.*)?") }
}
}
/**

View File

@@ -612,6 +612,25 @@ private class UseStateStep extends PreCallGraphStep {
}
}
/**
* Step through a `useRef` call.
*
* It returns an object with a single property (`current`) initialized to the initial value.
*
* For example:
* ```js
* const inputRef1 = useRef(initialValue);
* ```
*/
private class UseRefStep extends PreCallGraphStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode call | call = react().getAMemberCall("useRef") |
pred = call.getArgument(0) and // initial state
succ = call.getAPropertyRead("current")
)
}
}
/**
* A step through a React context object.
*
@@ -785,6 +804,17 @@ private class ReactRouterLocationSource extends DOM::LocationSource::Range {
}
}
private class UseRefDomValueSource extends DOM::DomValueSource::Range {
UseRefDomValueSource() {
this =
any(JsxAttribute attrib | attrib.getName() = "ref")
.getValue()
.flow()
.getALocalSource()
.getAPropertyRead("current")
}
}
/**
* Gets a reference to a function which, if called with a React component, returns wrapped
* version of that component, which we model as a direct reference to the underlying component.

View File

@@ -97,7 +97,7 @@ class ExternalApiDataNode extends DataFlow::Node instanceof Sink { }
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flow(_, this) }
UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flowTo(this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() { ExternalAPIUsedWithUntrustedDataFlow::flow(result, this) }
@@ -110,7 +110,7 @@ private newtype TExternalApi =
/** An external API sink with `name`. */
MkExternalApiNode(string name) {
exists(Sink sink |
ExternalAPIUsedWithUntrustedDataFlow::flow(_, sink) and
ExternalAPIUsedWithUntrustedDataFlow::flowTo(sink) and
name = sink.getApiName()
)
}