Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7b215ec

Browse files
author
Esben Sparre Andreasen
committed
JS: recognize defensive programming patterns using typeof
1 parent c403416 commit 7b215ec

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

javascript/ql/src/semmle/javascript/DefensiveProgramming.qll

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,96 @@ module Internal {
317317

318318
}
319319

320+
/**
321+
* A test for the value of a `typeof` expression.
322+
*/
323+
private class TypeofTest extends EqualityTest {
324+
Expr operand;
325+
326+
TypeofTag tag;
327+
328+
TypeofTest() {
329+
exists (Expr op1, Expr op2 |
330+
hasOperands(op1, op2) |
331+
operand = op1.(TypeofExpr).getOperand() and
332+
op2.mayHaveStringValue(tag)
333+
)
334+
}
335+
336+
boolean getTheTestResult() {
337+
exists (boolean testResult |
338+
testResult = true and operand.analyze().getTheType().getTypeofTag() = tag or
339+
testResult = false and not operand.analyze().getAType().getTypeofTag() = tag |
340+
if getPolarity() = true then
341+
result = testResult
342+
else
343+
result = testResult.booleanNot()
344+
)
345+
}
346+
347+
/**
348+
* Gets the operand used in the `typeof` expression.
349+
*/
350+
Expr getOperand() {
351+
result = operand
352+
}
353+
354+
/**
355+
* Gets the `typeof` tag that is tested.
356+
*/
357+
TypeofTag getTag() {
358+
result = tag
359+
}
360+
}
361+
362+
/**
363+
* A defensive expression that tests if an expression has type `function`.
364+
*/
365+
private class FunctionTypeGuard extends DefensiveExpression {
366+
367+
TypeofTest test;
368+
369+
boolean polarity;
370+
371+
FunctionTypeGuard() {
372+
exists (Expr guard, VarRef guardVar, VarRef useVar |
373+
this = guard.flow() and
374+
test = stripNotsAndParens(guard, polarity) and
375+
test.getOperand() = guardVar and
376+
guardVar.getVariable() = useVar.getVariable() |
377+
getAGuardedExpr(guard).stripParens().(NonFunctionCallCrashUse).getVulnerableSubexpression() = useVar
378+
) and
379+
test.getTag() = "function"
380+
}
381+
382+
override boolean getTheTestResult() {
383+
polarity = true and result = test.getTheTestResult()
384+
or
385+
polarity = false and result = test.getTheTestResult().booleanNot()
386+
}
387+
388+
}
389+
390+
/**
391+
* A test for `undefined` using a `typeof` expression.
392+
*/
393+
private class TypeofUndefinedTest extends UndefinedNullTest {
394+
395+
TypeofTest test;
396+
397+
TypeofUndefinedTest() {
398+
this = test and
399+
test.getTag() = "undefined"
400+
}
401+
402+
override boolean getTheTestResult() {
403+
result = test.getTheTestResult()
404+
}
405+
406+
override Expr getOperand() {
407+
result = test.getOperand()
408+
}
409+
410+
}
411+
320412
}

0 commit comments

Comments
 (0)