Compare commits

...

8 Commits

Author SHA1 Message Date
Alex Eyers-Taylor
1b2689cbb8 Python: Remove join order hints that don't work. 2025-05-02 18:42:29 +01:00
Alex Eyers-Taylor
5f7757740a JS: Prevent some bad joins under RTJO. 2025-05-02 16:48:20 +01:00
Alex Eyers-Taylor
b8c9f72e60 Fix a bad join order on locations. 2025-05-02 16:48:19 +01:00
Alex Eyers-Taylor
f948d1cf4e Use late inline to deal with bad join orders from type tracking. 2025-05-02 16:48:19 +01:00
Alex Eyers-Taylor
689a32e34f Ruby: Avoid a forced CP. 2025-05-02 16:48:19 +01:00
Alex Eyers-Taylor
56ce6f5bc9 CPP: Add noinline so size estimates are better. 2025-05-02 16:48:18 +01:00
Alex Eyers-Taylor
46b68ab2f4 Extarct to predicate for RTJO 2025-05-02 16:48:18 +01:00
Alex Eyers-Taylor
33ecb9b07d CPP: Pull rank into predicate for RTJO. 2025-05-02 16:48:18 +01:00
9 changed files with 56 additions and 29 deletions

View File

@@ -88,6 +88,7 @@ class Declaration extends Locatable, @declaration {
* *
* See the 3-argument `hasQualifiedName` for examples. * See the 3-argument `hasQualifiedName` for examples.
*/ */
pragma[noinline]
predicate hasQualifiedName(string namespaceQualifier, string baseName) { predicate hasQualifiedName(string namespaceQualifier, string baseName) {
this.hasQualifiedName(namespaceQualifier, "", baseName) this.hasQualifiedName(namespaceQualifier, "", baseName)
} }

View File

@@ -815,10 +815,15 @@ private predicate isRelatableMemoryLocation(VariableMemoryLocation vml) {
vml.getStartBitOffset() != Ints::unknown() vml.getStartBitOffset() != Ints::unknown()
} }
pragma[noinline]
private int getRank(VirtualVariable vvar, IntValue offset) {
offset = rank[result](IntValue offset_ | isRelevantOffset(vvar, offset_))
}
private predicate isCoveredOffset(Allocation var, int offsetRank, VariableMemoryLocation vml) { private predicate isCoveredOffset(Allocation var, int offsetRank, VariableMemoryLocation vml) {
exists(int startRank, int endRank, VirtualVariable vvar | exists(int startRank, int endRank, VirtualVariable vvar |
vml.getStartBitOffset() = rank[startRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and startRank = getRank(vvar, vml.getStartBitOffset()) and
vml.getEndBitOffset() = rank[endRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and endRank = getRank(vvar, vml.getEndBitOffset()) and
var = vml.getAnAllocation() and var = vml.getAnAllocation() and
vvar = vml.getVirtualVariable() and vvar = vml.getVirtualVariable() and
isRelatableMemoryLocation(vml) and isRelatableMemoryLocation(vml) and

View File

@@ -117,7 +117,11 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
* directly accessed by the function. * directly accessed by the function.
*/ */
final predicate hasUserVariable(Variable varUsed, CppType type) { final predicate hasUserVariable(Variable varUsed, CppType type) {
( this.hasUserVariable1(varUsed) and
type = getTypeForPRValue(getVariableType(varUsed))
}
private predicate hasUserVariable1(Variable varUsed) {
( (
varUsed instanceof GlobalOrNamespaceVariable varUsed instanceof GlobalOrNamespaceVariable
or or
@@ -135,8 +139,6 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
varUsed.(LocalScopeVariable).getEnclosingElement*() = var varUsed.(LocalScopeVariable).getEnclosingElement*() = var
or or
varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = var varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = var
) and
type = getTypeForPRValue(getVariableType(varUsed))
} }
} }

View File

@@ -1372,7 +1372,7 @@ module API {
exists(DataFlow::TypeBackTracker t, StepSummary summary, DataFlow::Node next | exists(DataFlow::TypeBackTracker t, StepSummary summary, DataFlow::Node next |
next = trackDefNode(nd, t) and next = trackDefNode(nd, t) and
StepSummary::step(prev, next, summary) and StepSummary::step(prev, next, summary) and
result = t.prepend(summary) result = t.prepend_cached(summary)
) )
} }

View File

@@ -138,7 +138,7 @@ class TypeTracker extends TTypeTracker {
TypeTracker step(DataFlow::SourceNode pred, DataFlow::SourceNode succ) { TypeTracker step(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
exists(StepSummary summary | exists(StepSummary summary |
StepSummary::step(pred, succ, summary) and StepSummary::step(pred, succ, summary) and
result = this.append(summary) result = pragma[only_bind_out](this).append(summary)
) )
} }
@@ -224,8 +224,16 @@ class TypeBackTracker extends TTypeBackTracker {
TypeBackTracker() { this = MkTypeBackTracker(hasReturn, prop) } TypeBackTracker() { this = MkTypeBackTracker(hasReturn, prop) }
/** Gets the summary resulting from prepending `step` to this type-tracking summary. */ /** Gets the summary resulting from prepending `step` to this type-tracking summary. */
bindingset[this, step]
pragma[inline_late]
TypeBackTracker prepend(StepSummary step) { result = this.prepend_cached(step) }
/**
* INTERNAL: DO NOT USE
* Raw version of prepend.
*/
cached cached
TypeBackTracker prepend(StepSummary step) { TypeBackTracker prepend_cached(StepSummary step) {
Stages::TypeTracking::ref() and Stages::TypeTracking::ref() and
step = LevelStep() and step = LevelStep() and
result = this result = this

View File

@@ -236,7 +236,7 @@ module Stages {
or or
exists(any(DataFlow::TypeTracker t).append(_)) exists(any(DataFlow::TypeTracker t).append(_))
or or
exists(any(DataFlow::TypeBackTracker t).prepend(_)) exists(any(DataFlow::TypeBackTracker t).prepend_cached(_))
or or
DataFlow::functionForwardingStep(_, _) DataFlow::functionForwardingStep(_, _)
or or

View File

@@ -12,8 +12,11 @@
import javascript import javascript
from LabeledStmt l, Case c int labelInCaseStartColumn(Case c, LabeledStmt l) {
where
l = c.getAChildStmt+() and l = c.getAChildStmt+() and
l.getLocation().getStartColumn() = c.getLocation().getStartColumn() result = l.getLocation().getStartColumn()
}
from LabeledStmt l, Case c
where labelInCaseStartColumn(c, l) = c.getLocation().getStartColumn()
select l.getChildExpr(0), "Non-case labels in switch statements are confusing." select l.getChildExpr(0), "Non-case labels in switch statements are confusing."

View File

@@ -187,7 +187,7 @@ class PointsToContext extends TPointsToContext {
pragma[inline] pragma[inline]
predicate appliesTo(ControlFlowNode n) { predicate appliesTo(ControlFlowNode n) {
exists(Scope s | exists(Scope s |
this.appliesToScope(pragma[only_bind_into](s)) and pragma[only_bind_into](s) = n.getScope() this.appliesToScope(s) and s = n.getScope()
) )
} }

View File

@@ -54,6 +54,14 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode {
override DataFlow::Node getAUrlPart() { override DataFlow::Node getAUrlPart() {
result = request.getArgument(0) result = request.getArgument(0)
or or
result = this.getAUrlPartFromConstructor()
}
/**
* Gets a node that contributes to the URL of the request
* indirectly, through the constructor.
*/
private DataFlow::Node getAUrlPartFromConstructor() {
// Net::HTTP.new(...).get(...) // Net::HTTP.new(...).get(...)
exists(API::Node new | exists(API::Node new |
new = API::getTopLevelMember("Net").getMember("HTTP").getInstance() and new = API::getTopLevelMember("Net").getMember("HTTP").getInstance() and