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.
*/
pragma[noinline]
predicate hasQualifiedName(string namespaceQualifier, string baseName) {
this.hasQualifiedName(namespaceQualifier, "", baseName)
}

View File

@@ -815,10 +815,15 @@ private predicate isRelatableMemoryLocation(VariableMemoryLocation vml) {
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) {
exists(int startRank, int endRank, VirtualVariable vvar |
vml.getStartBitOffset() = rank[startRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and
vml.getEndBitOffset() = rank[endRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and
startRank = getRank(vvar, vml.getStartBitOffset()) and
endRank = getRank(vvar, vml.getEndBitOffset()) and
var = vml.getAnAllocation() and
vvar = vml.getVirtualVariable() and
isRelatableMemoryLocation(vml) and

View File

@@ -117,27 +117,29 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
* directly accessed by the function.
*/
final predicate hasUserVariable(Variable varUsed, CppType type) {
(
(
varUsed instanceof GlobalOrNamespaceVariable
or
varUsed instanceof StaticLocalVariable
or
varUsed instanceof MemberVariable and not varUsed instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = varUsed and
getEnclosingVariable(access) = var
)
or
var = varUsed
or
varUsed.(LocalScopeVariable).getEnclosingElement*() = var
or
varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = var
) and
this.hasUserVariable1(varUsed) and
type = getTypeForPRValue(getVariableType(varUsed))
}
private predicate hasUserVariable1(Variable varUsed) {
(
varUsed instanceof GlobalOrNamespaceVariable
or
varUsed instanceof StaticLocalVariable
or
varUsed instanceof MemberVariable and not varUsed instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = varUsed and
getEnclosingVariable(access) = var
)
or
var = varUsed
or
varUsed.(LocalScopeVariable).getEnclosingElement*() = var
or
varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = var
}
}
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }

View File

@@ -1372,7 +1372,7 @@ module API {
exists(DataFlow::TypeBackTracker t, StepSummary summary, DataFlow::Node next |
next = trackDefNode(nd, t) 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) {
exists(StepSummary summary |
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) }
/** 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
TypeBackTracker prepend(StepSummary step) {
TypeBackTracker prepend_cached(StepSummary step) {
Stages::TypeTracking::ref() and
step = LevelStep() and
result = this

View File

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

View File

@@ -12,8 +12,11 @@
import javascript
from LabeledStmt l, Case c
where
int labelInCaseStartColumn(Case c, LabeledStmt l) {
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."

View File

@@ -187,7 +187,7 @@ class PointsToContext extends TPointsToContext {
pragma[inline]
predicate appliesTo(ControlFlowNode n) {
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() {
result = request.getArgument(0)
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(...)
exists(API::Node new |
new = API::getTopLevelMember("Net").getMember("HTTP").getInstance() and