mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
JavaScript: Remove deprecated queries.
These queries have all been deprecated since 1.17 (released in July 2018). I think it's time to say goodbye.
This commit is contained in:
@@ -42,3 +42,21 @@
|
||||
## Changes to QL libraries
|
||||
|
||||
* `Expr.getDocumentation()` now handles chain assignments.
|
||||
|
||||
## Removal of deprecated queries
|
||||
|
||||
The following queries (deprecated since 1.17) are no longer available in the distribution:
|
||||
|
||||
* Builtin redefined (js/builtin-redefinition)
|
||||
* Inefficient method definition (js/method-definition-in-constructor)
|
||||
* Bad parity check (js/incomplete-parity-check)
|
||||
* Potentially misspelled property or variable name (js/wrong-capitalization)
|
||||
* Unknown JSDoc tag (js/jsdoc/unknown-tag-type)
|
||||
* Invalid JSLint directive (js/jslint/invalid-directive)
|
||||
* Malformed JSLint directive (js/jslint/malformed-directive)
|
||||
* Use of HTML comments (js/html-comment)
|
||||
* Multi-line string literal (js/multi-line-string)
|
||||
* Octal literal (js/octal-literal)
|
||||
* Reserved word used as variable name (js/use-of-reserved-word)
|
||||
* Trailing comma in array or object expressions (js/trailing-comma-in-array-or-object)
|
||||
* Call to parseInt without radix (js/parseint-without-radix)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
+ semmlecode-javascript-queries/Declarations/BuiltinRedefined.ql: /Maintainability/Declarations
|
||||
+ semmlecode-javascript-queries/Declarations/InefficientMethodDefinition.ql: /Maintainability/Declarations
|
||||
+ semmlecode-javascript-queries/Expressions/BadParityCheck.ql: /Correctness/Expressions
|
||||
+ semmlecode-javascript-queries/Expressions/HapaxLegomenon.ql: /Correctness/Expressions
|
||||
+ semmlecode-javascript-queries/JSDoc/UnknownTagType.ql: /Readability/JSDoc
|
||||
+ semmlecode-javascript-queries/JSLint/InvalidJSLintDirective.ql: /Frameworks/JSLint
|
||||
+ semmlecode-javascript-queries/JSLint/MalformedJSLintDirective.ql: /Frameworks/JSLint
|
||||
+ semmlecode-javascript-queries/LanguageFeatures/HTMLComments.ql: /Maintainability/Language Features
|
||||
+ semmlecode-javascript-queries/LanguageFeatures/MultilineStringLiteral.ql: /Readability/Language Features
|
||||
+ semmlecode-javascript-queries/LanguageFeatures/ReservedWords.ql: /Maintainability/Language Features
|
||||
+ semmlecode-javascript-queries/LanguageFeatures/TrailingComma.ql: /Correctness/Language Features
|
||||
+ semmlecode-javascript-queries/LanguageFeatures/OctalLiteral.ql: /Maintainability/Language Features
|
||||
+ semmlecode-javascript-queries/StandardLibrary/ParseIntRadix.ql: /Maintainability/Standard Library
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Builtin functions and objects defined in the JavaScript standard library can be shadowed or redefined in user code.
|
||||
This is confusing and makes code hard to understand, so it should be avoided.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Refactor the code to avoid shadowing or redefinition. For example, if a local variable has the same name as a standard
|
||||
library builtin, it should be renamed.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following example, the user-defined function <code>eval</code> shadows the builtin function <code>eval</code>
|
||||
defined in the standard library. It could be renamed <code>evaluate</code> to avoid confusion.
|
||||
</p>
|
||||
|
||||
<sample src="examples/BuiltinRedefined.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Section 15. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* @name Builtin redefined
|
||||
* @description Standard library functions can be redefined, but this should be avoided
|
||||
* since it makes code hard to read and maintain.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/builtin-redefinition
|
||||
* @tags maintainability
|
||||
* @precision medium
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import Definitions
|
||||
|
||||
/**
|
||||
* Holds if `id` is a redefinition of a standard library function that is considered
|
||||
* acceptable since it merely introduces a local alias to the standard function of
|
||||
* the same name.
|
||||
*/
|
||||
predicate acceptableRedefinition(Identifier id) {
|
||||
// function(x, y, undefined) { ... }(23, 42)
|
||||
id.getName() = "undefined" and
|
||||
exists(ImmediatelyInvokedFunctionExpr iife |
|
||||
id = iife.getParameter(iife.getInvocation().getNumArgument())
|
||||
)
|
||||
or
|
||||
// Date = global.Date
|
||||
exists(AssignExpr assgn |
|
||||
id = assgn.getTarget() and
|
||||
id.getName() = assgn.getRhs().getUnderlyingValue().(PropAccess).getPropertyName()
|
||||
)
|
||||
or
|
||||
// var Date = global.Date
|
||||
exists(VariableDeclarator decl |
|
||||
id = decl.getBindingPattern() and
|
||||
id.getName() = decl.getInit().getUnderlyingValue().(PropAccess).getPropertyName()
|
||||
)
|
||||
}
|
||||
|
||||
from DefiningIdentifier id, string name
|
||||
where
|
||||
not id.inExternsFile() and
|
||||
name = id.getName() and
|
||||
name
|
||||
.regexpMatch("Object|Function|Array|String|Boolean|Number|Math|Date|RegExp|Error|" +
|
||||
"NaN|Infinity|undefined|eval|parseInt|parseFloat|isNaN|isFinite|" +
|
||||
"decodeURI|decodeURIComponent|encodeURI|encodeURIComponent") and
|
||||
not acceptableRedefinition(id)
|
||||
select id, "Redefinition of " + name + "."
|
||||
@@ -1,46 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Defining a method by assigning a closure to a property of the receiver object in the constructor
|
||||
is inefficient, since a new closure is created for every instance. This wastes heap space and may
|
||||
interfere with JIT compilation.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Assign the function to a property of the prototype object instead. That way, all instances share
|
||||
the same closure.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following example, constructor <code>Point</code> defines method <code>move</code> by creating
|
||||
a new closure and storing it in the <code>move</code> property of each new instance. Consequently,
|
||||
<code>p.move</code> and <code>q.move</code> are different methods.
|
||||
</p>
|
||||
|
||||
<sample src="examples/InefficientMethodDefinition.js" />
|
||||
|
||||
<p>
|
||||
It is better to instead define <code>move</code> on the prototype object <code>Point.prototype</code>
|
||||
like this:
|
||||
</p>
|
||||
|
||||
<sample src="examples/InefficientMethodDefinitionGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">Inheritance and the prototype chain</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* @name Inefficient method definition
|
||||
* @description Defining methods in the constructor (as opposed to adding them to the
|
||||
* prototype object) is inefficient.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/method-definition-in-constructor
|
||||
* @tags efficiency
|
||||
* maintainability
|
||||
* @precision medium
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.RestrictedLocations
|
||||
|
||||
/**
|
||||
* Holds if `stmt` is of the form `this.<name> = <method>;`.
|
||||
*/
|
||||
predicate methodDefinition(ExprStmt stmt, string name, Function method) {
|
||||
exists(AssignExpr assgn, PropAccess pacc |
|
||||
assgn = stmt.getExpr() and
|
||||
pacc = assgn.getLhs() and
|
||||
pacc.getBase() instanceof ThisExpr and
|
||||
name = pacc.getPropertyName() and
|
||||
method = assgn.getRhs()
|
||||
)
|
||||
}
|
||||
|
||||
from Function ctor, ExprStmt defn, string name, Function method
|
||||
where
|
||||
not ctor instanceof ImmediatelyInvokedFunctionExpr and
|
||||
defn = ctor.getABodyStmt() and
|
||||
methodDefinition(defn, name, method) and
|
||||
// if the method captures a local variable of the constructor, it cannot
|
||||
// easily be moved to the constructor object
|
||||
not exists(Variable v | v.getScope() = ctor.getScope() |
|
||||
v.getAnAccess().getContainer().getEnclosingContainer*() = method
|
||||
)
|
||||
select defn.(FirstLineOf),
|
||||
name + " should be added to the prototype object rather than to each instance."
|
||||
@@ -1,45 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Avoid using <code>x % 2 === 1</code> or <code>x % 2 > 0</code> to check whether a number
|
||||
<code>x</code> is odd, or <code>x % 2 !== 1</code> to check whether it is even.
|
||||
Such code does not work for negative numbers: for example, <code>-5 % 2</code> equals
|
||||
<code>-1</code>, not <code>1</code>.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Consider using <code>x % 2 !== 0</code> to check for odd parity and <code>x % 2 === 0</code>
|
||||
to check for even parity.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code snippet does not detect -9 as an odd number because <code>-9 % 2</code>
|
||||
is <code>-1</code>, not <code>1</code>.</p>
|
||||
|
||||
<sample src="examples/BadParityCheck.js" />
|
||||
|
||||
<p>
|
||||
The check should be rewritten as follows:
|
||||
</p>
|
||||
|
||||
<sample src="examples/BadParityCheckGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>J. Bloch and N. Gafter, <em>Java Puzzlers: Traps, Pitfalls, and Corner Cases</em>, Puzzle 1. Addison-Wesley, 2005.</li>
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Section 11.5.3. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,105 +0,0 @@
|
||||
/**
|
||||
* @name Bad parity check
|
||||
* @description Ensure that parity checks take negative numbers into account.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/incomplete-parity-check
|
||||
* @tags reliability
|
||||
* correctness
|
||||
* external/cwe/cwe-480
|
||||
* @precision low
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/*
|
||||
* The following predicates implement a simple analysis for identifying
|
||||
* expressions that are guaranteed to only evaluate to non-negative numbers:
|
||||
*
|
||||
* - non-negative number literals
|
||||
* - applications of (), ++, + to expressions known to be non-negative
|
||||
* - references to local variables that are only assigned non-negative values,
|
||||
* never decremented, and never subjected to any compound assignments except
|
||||
* += where the rhs is known to be non-negative
|
||||
*
|
||||
* This is a greatest-fixpoint problem: if we have `x = 0`, `y = x`, `x = y`,
|
||||
* we want to conclude that both `x` and `y` are non-negative. Hence we have
|
||||
* to implement the analysis the other way around, as a conservative check
|
||||
* for negativity.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds if `e` is an expression that is relevant for the maybe-negative analysis.
|
||||
*/
|
||||
predicate relevant(Expr e) {
|
||||
// base case: left operands of `%`
|
||||
exists(ModExpr me | e = me.getLeftOperand())
|
||||
or
|
||||
// first inductive case: downward AST traversal
|
||||
relevant(e.getParentExpr())
|
||||
or
|
||||
// second inductive case: following variable assignments
|
||||
exists(Variable v | relevant(v.getAnAccess()) | e = v.getAnAssignedExpr())
|
||||
}
|
||||
|
||||
/** Holds if `e` could evaluate to a negative number. */
|
||||
predicate maybeNegative(Expr e) {
|
||||
relevant(e) and
|
||||
if exists(e.getIntValue())
|
||||
then e.getIntValue() < 0
|
||||
else
|
||||
if e instanceof ParExpr
|
||||
then maybeNegative(e.(ParExpr).getExpression())
|
||||
else
|
||||
if e instanceof IncExpr
|
||||
then maybeNegative(e.(IncExpr).getOperand())
|
||||
else
|
||||
if e instanceof VarAccess
|
||||
then maybeNegativeVar(e.(VarAccess).getVariable())
|
||||
else
|
||||
if e instanceof AddExpr
|
||||
then maybeNegative(e.(AddExpr).getAnOperand())
|
||||
else
|
||||
// anything else is considered to possibly be negative
|
||||
any()
|
||||
}
|
||||
|
||||
/** Holds if `v` could be assigned a negative number. */
|
||||
predicate maybeNegativeVar(Variable v) {
|
||||
v.isGlobal()
|
||||
or
|
||||
v.isParameter()
|
||||
or
|
||||
// is v ever assigned a potentially negative value?
|
||||
maybeNegative(v.getAnAssignedExpr())
|
||||
or
|
||||
// is v ever decremented?
|
||||
exists(DecExpr dec | dec.getOperand().getUnderlyingReference() = v.getAnAccess())
|
||||
or
|
||||
// is v ever subject to a compound assignment other than +=, or to
|
||||
// += with potentially negative rhs?
|
||||
exists(CompoundAssignExpr assgn | assgn.getTarget() = v.getAnAccess() |
|
||||
not assgn instanceof AssignAddExpr or
|
||||
maybeNegative(assgn.getRhs())
|
||||
)
|
||||
}
|
||||
|
||||
from Comparison cmp, ModExpr me, int num, string parity
|
||||
where
|
||||
cmp.getAnOperand().stripParens() = me and
|
||||
cmp.getAnOperand().getIntValue() = num and
|
||||
me.getRightOperand().getIntValue() = 2 and
|
||||
maybeNegative(me.getLeftOperand()) and
|
||||
(
|
||||
(cmp instanceof EqExpr or cmp instanceof StrictEqExpr) and
|
||||
num = 1 and
|
||||
parity = "oddness"
|
||||
or
|
||||
(cmp instanceof NEqExpr or cmp instanceof StrictNEqExpr) and
|
||||
num = 1 and
|
||||
parity = "evenness"
|
||||
or
|
||||
cmp instanceof GTExpr and num = 0 and parity = "oddness"
|
||||
)
|
||||
select cmp, "Test for " + parity + " does not take negative numbers into account."
|
||||
@@ -1,56 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
In JavaScript, properties of objects do not have to be declared and can be dynamically added
|
||||
and removed at runtime. Thus, if a property name is misspelled, this is not detected by the
|
||||
compiler, and may lead to an error at runtime. The same problem occurs with misspelled
|
||||
global variables.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This rule flags property names and global variables that are mentioned only once, but where
|
||||
a different capitalization of the same name is used in multiple other places, suggesting a typo.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Check whether the name has been misspelled. If the name is correct, consider using
|
||||
a <a href="http://www.jslint.com/help.html#properties">JSLint-style</a>
|
||||
<code>/*property ...*/</code> directive to document the existence of this property,
|
||||
or provide an externs file declaring the property.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code snippet contains two uses of the <code>log</code> method, but only
|
||||
one use of the <code>Log</code> method. This suggests that <code>Log</code> may be a typo
|
||||
for <code>log</code>.
|
||||
</p>
|
||||
|
||||
<sample src="examples/HapaxLegomenon.js" />
|
||||
|
||||
<p>
|
||||
If the use of <code>Log</code> is, in fact, a typo, it should be corrected. Otherwise, a
|
||||
<code>properties</code> directive can be introduced to document the fact that both
|
||||
<code>log</code> and <code>Log</code> properties exist:
|
||||
</p>
|
||||
|
||||
<sample src="examples/HapaxLegomenonGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>JSLint: <a href="http://www.jslint.com/help.html#properties">Property</a>.</li>
|
||||
<li>Google Closure Tools: <a href="https://developers.google.com/closure/compiler/docs/api-tutorial3?csw=1#externs">Declaring externs</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,91 +0,0 @@
|
||||
/**
|
||||
* @name Potentially misspelled property or variable name
|
||||
* @description A property or variable is only mentioned once, but there is one with the same name
|
||||
* in different capitalization that is mentioned more than once, suggesting that this
|
||||
* may be a typo.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id js/wrong-capitalization
|
||||
* @tags reliability
|
||||
* @precision low
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/** Gets the number of identifiers and string literals that refer to `name`. */
|
||||
int countOccurrences(string name) {
|
||||
(
|
||||
exists(PropAccess pacc | name = pacc.getPropertyName()) or
|
||||
exists(VarAccess acc | name = acc.getName())
|
||||
) and
|
||||
result = strictcount(Expr id |
|
||||
id.(Identifier).getName() = name
|
||||
or
|
||||
// count string literals as well to capture meta-programming
|
||||
id.getStringValue() = name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to an undeclared variable or property that is only referenced
|
||||
* once in the entire program.
|
||||
*/
|
||||
abstract class Hapax extends @expr {
|
||||
/** Gets the name of the accessed variable or property. */
|
||||
abstract string getName();
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.(Expr).toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to a property that is covered neither by a JSLint property declaration
|
||||
* nor by an externs declaration, and that is only mentioned once in the entire program.
|
||||
*/
|
||||
class UndeclaredPropertyAccess extends Hapax, @dotexpr {
|
||||
UndeclaredPropertyAccess() {
|
||||
exists(string name | name = this.(DotExpr).getPropertyName() |
|
||||
countOccurrences(name) = 1 and
|
||||
not exists(JSLintProperties jslpd | jslpd.appliesTo(this) and jslpd.getAProperty() = name) and
|
||||
not exists(ExternalMemberDecl emd | emd.getProperty() = this)
|
||||
)
|
||||
}
|
||||
|
||||
override string getName() { result = this.(DotExpr).getPropertyName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to a global variable that is neither declared nor covered by a linter
|
||||
* directive, and that is only mentioned once in the entire program.
|
||||
*/
|
||||
class UndeclaredGlobal extends Hapax, @varaccess {
|
||||
UndeclaredGlobal() {
|
||||
exists(GlobalVariable gv, string name | this = gv.getAnAccess() and name = gv.getName() |
|
||||
countOccurrences(name) = 1 and
|
||||
not exists(Linting::GlobalDeclaration glob | glob.declaresGlobalForAccess(this)) and
|
||||
not exists(gv.getADeclaration())
|
||||
)
|
||||
}
|
||||
|
||||
override string getName() { result = this.(VarAccess).getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of occurrences of `m`, which is the same as `hapax`
|
||||
* except for capitalization, ensuring that it occurs at least twice.
|
||||
*/
|
||||
int candidateSpellingCount(Hapax hapax, string m) {
|
||||
exists(string n | n = hapax.getName() |
|
||||
m.toLowerCase() = n.toLowerCase() and
|
||||
m != n and
|
||||
result = countOccurrences(m) and
|
||||
result > 1
|
||||
)
|
||||
}
|
||||
|
||||
from Hapax hapax, string n, string m
|
||||
where
|
||||
n = hapax.getName() and
|
||||
candidateSpellingCount(hapax, m) = max(candidateSpellingCount(hapax, _))
|
||||
select hapax.(Expr), "'" + n + "' is mentioned only once; it may be a typo for '" + m + "'."
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Non-standard JSDoc tags are undesirable, since JSDoc-processing tools will either ignore
|
||||
them or treat them as plain text.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Check whether the tag name is misspelled, or consult the JSDoc documentation to find out
|
||||
what standard tags are available.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following example, the constructor <code>Message</code> has a JSDoc comment describing
|
||||
its parameters, but the second <code>@param</code> tag has been misspelled as
|
||||
<code>@parma</code>.
|
||||
</p>
|
||||
|
||||
<sample src="examples/UnknownTagType.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Use JSDoc: <a href="http://usejsdoc.org/index.html">Tag Dictionary</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,139 +0,0 @@
|
||||
/**
|
||||
* @name Unknown JSDoc tag
|
||||
* @description A JSDoc tag with a non-standard tag type will either be ignored or treated as plain
|
||||
* text by JSDoc-processing tools.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/jsdoc/unknown-tag-type
|
||||
* @tags maintainability
|
||||
* readability
|
||||
* documentation
|
||||
* @precision low
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/** Holds if `tp` is a standard tag type. */
|
||||
predicate knownTagType(string tp) {
|
||||
tp = "abstract" or
|
||||
tp = "access" or
|
||||
tp = "alias" or
|
||||
tp = "api" or
|
||||
tp = "arg" or
|
||||
tp = "argument" or
|
||||
tp = "augments" or
|
||||
tp = "author" or
|
||||
tp = "borrows" or
|
||||
tp = "bug" or
|
||||
tp = "callback" or
|
||||
tp = "category" or
|
||||
tp = "class" or
|
||||
tp = "classdesc" or
|
||||
tp = "const" or
|
||||
tp = "constant" or
|
||||
tp = "constructor" or
|
||||
tp = "constructs" or
|
||||
tp = "copyright" or
|
||||
tp = "default" or
|
||||
tp = "defaultvalue" or
|
||||
tp = "define" or
|
||||
tp = "depend" or
|
||||
tp = "depends" or
|
||||
tp = "deprecated" or
|
||||
tp = "desc" or
|
||||
tp = "description" or
|
||||
tp = "dict" or
|
||||
tp = "emits" or
|
||||
tp = "enum" or
|
||||
tp = "event" or
|
||||
tp = "example" or
|
||||
tp = "exception" or
|
||||
tp = "export" or
|
||||
tp = "exports" or
|
||||
tp = "expose" or
|
||||
tp = "extends" or
|
||||
tp = "external" or
|
||||
tp = "externs" or
|
||||
tp = "field" or
|
||||
tp = "file" or
|
||||
tp = "fileoverview" or
|
||||
tp = "final" or
|
||||
tp = "fires" or
|
||||
tp = "flow" or
|
||||
tp = "func" or
|
||||
tp = "function" or
|
||||
tp = "global" or
|
||||
tp = "host" or
|
||||
tp = "ignore" or
|
||||
tp = "implements" or
|
||||
tp = "implicitCast" or
|
||||
tp = "inheritDoc" or
|
||||
tp = "inner" or
|
||||
tp = "interface" or
|
||||
tp = "internal" or
|
||||
tp = "instance" or
|
||||
tp = "kind" or
|
||||
tp = "lends" or
|
||||
tp = "license" or
|
||||
tp = "link" or
|
||||
tp = "member" or
|
||||
tp = "memberof" or
|
||||
tp = "memberOf" or
|
||||
tp = "method" or
|
||||
tp = "mixes" or
|
||||
tp = "mixin" or
|
||||
tp = "modifies" or
|
||||
tp = "module" or
|
||||
tp = "modName" or
|
||||
tp = "mods" or
|
||||
tp = "name" or
|
||||
tp = "namespace" or
|
||||
tp = "ngInject" or
|
||||
tp = "noalias" or
|
||||
tp = "nocompile" or
|
||||
tp = "nosideeffects" or
|
||||
tp = "note" or
|
||||
tp = "override" or
|
||||
tp = "overview" or
|
||||
tp = "owner" or
|
||||
tp = "package" or
|
||||
tp = "param" or
|
||||
tp = "preserve" or
|
||||
tp = "preserveTry" or
|
||||
tp = "private" or
|
||||
tp = "prop" or
|
||||
tp = "property" or
|
||||
tp = "protected" or
|
||||
tp = "providesModule" or
|
||||
tp = "public" or
|
||||
tp = "readonly" or
|
||||
tp = "requires" or
|
||||
tp = "returns" or
|
||||
tp = "return" or
|
||||
tp = "see" or
|
||||
tp = "since" or
|
||||
tp = "static" or
|
||||
tp = "struct" or
|
||||
tp = "summary" or
|
||||
tp = "supported" or
|
||||
tp = "suppress" or
|
||||
tp = "template" or
|
||||
tp = "this" or
|
||||
tp = "throws" or
|
||||
tp = "todo" or
|
||||
tp = "tutorial" or
|
||||
tp = "type" or
|
||||
tp = "typedef" or
|
||||
tp = "var" or
|
||||
tp = "variation" or
|
||||
tp = "version" or
|
||||
tp = "virtual" or
|
||||
tp = "visibility" or
|
||||
tp = "wizaction" or
|
||||
tp = "wizmodule"
|
||||
}
|
||||
|
||||
from JSDocTag tag
|
||||
where not knownTagType(tag.getTitle())
|
||||
select tag, "Unknown tag type '" + tag.getTitle() + "'."
|
||||
@@ -1,26 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
JSLint directives must not start with a space. For example, <code>/* global window*/</code>
|
||||
is not a valid directive, and will not be recognized by JSLint.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Remove the space: <code>/*global window*/</code>.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<references>
|
||||
|
||||
|
||||
<li>JSLint: <a href="http://www.jslint.com/help.html">JSLint Help</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @name Invalid JSLint directive
|
||||
* @description A JSLint directive that has whitespace characters before the
|
||||
* directive name is not recognized by JSLint.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/jslint/invalid-directive
|
||||
* @tags maintainability
|
||||
* @precision medium
|
||||
* @deprecated JSLint is rarely used any more. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from SlashStarComment c
|
||||
where
|
||||
// use possessive quantifiers '*+' and '++' to avoid backtracking
|
||||
c
|
||||
.getText()
|
||||
.regexpMatch("\\s+(global|properties|property|jslint)\\s(\\s*+[a-zA-Z$_][a-zA-Z0-9$_]*+(\\s*+:\\s*+\\w++)?\\s*+,?)++\\s*")
|
||||
select c, "JSLint directives must not have whitespace characters before the directive name."
|
||||
@@ -1,49 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
JSLint directives must consist of a comma-separated list of flags, where each flag
|
||||
can optionally be followed by a colon and a value. The value may either be a number
|
||||
or a Boolean (that is, 'true' or 'false'). Directives must not contain other
|
||||
characters such as '*', which some editors may automatically insert after every line
|
||||
break when editing a block comment.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Insert commas where necessary and remove stray characters.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
For example, <code>/*jslint nomen:true vars:true*/</code> is not a well-formed
|
||||
JSLint directive; it should be replaced by <code>/*jslint nomen:true, vars:true*/</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is another example of a malformed JSLint directive:
|
||||
</p>
|
||||
|
||||
<sample src="examples/MalformedJSLintDirective.js" />
|
||||
|
||||
<p>
|
||||
It should be fixed as follows:
|
||||
</p>
|
||||
|
||||
<sample src="examples/MalformedJSLintDirectiveGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>JSLint: <a href="http://www.jslint.com/help.html">JSLint Help</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* @name Malformed JSLint directive
|
||||
* @description A malformed JSLint directive will be rejected by JSLint, and may be either
|
||||
* rejected or ignored by other tools.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/jslint/malformed-directive
|
||||
* @tags maintainability
|
||||
* @precision medium
|
||||
* @deprecated JSLint is rarely used any more. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from JSLintDirective dir, string flag, string flags, string directive
|
||||
where
|
||||
// a flag, optionally followed by a colon and a value, where the value may be
|
||||
// a Boolean or a number
|
||||
flag = "[a-zA-Z$_][a-zA-Z0-9$_]*(\\s*:\\s*(true|false|\\d+))?" and
|
||||
// a non-empty, comma-separated list of flags
|
||||
flags = "(" + flag + "\\s*,\\s*)*" + flag and
|
||||
// a word (which is the directive's name), followed by a possibly empty list of flags
|
||||
// note that there may be trailing whitespace, but no leading whitespace
|
||||
directive = "\\s*\\w+\\s+(" + flags + ")?\\s*" and
|
||||
not dir.getText().regexpMatch(directive)
|
||||
select dir, "Malformed JSLint directive."
|
||||
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
HTML comments are a technique for hiding JavaScript code from browsers that do not interpret <code>script</code>
|
||||
tags. Since all popular browsers have supported <code>script</code> tags for many years, this precaution is
|
||||
not needed any more.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Remove all HTML comments.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code block uses HTML comments to hide the <code>script</code> block from ancient browsers.
|
||||
</p>
|
||||
|
||||
<sample src="examples/HTMLComments.js" />
|
||||
|
||||
<p>
|
||||
Since such browsers are no longer widely used, the comments should be removed:
|
||||
</p>
|
||||
|
||||
<sample src="examples/HTMLCommentsGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>JavaScript Toolbox: <a href="http://www.javascripttoolbox.com/bestpractices/#comments">JavaScript Best Practices</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @name Use of HTML comments
|
||||
* @description HTML-style comments are not a standard ECMAScript feature and should be avoided.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/html-comment
|
||||
* @tags maintainability
|
||||
* language-features
|
||||
* external/cwe/cwe-758
|
||||
* @precision low
|
||||
* @deprecated HTML comments are recognized in the standard as an additional feature supported by
|
||||
* web browsers. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from HtmlLineComment c
|
||||
select c, "Do not use HTML comments."
|
||||
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Multi-line string literals are not supported on all platforms, and thus should be avoided.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Replace multi-line string literals by multiple strings concatenated with the <code>+</code> operator.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following example contains a string literal spanning three lines:
|
||||
</p>
|
||||
|
||||
<sample src="examples/MultilineStringLiteral.js" />
|
||||
|
||||
<p>
|
||||
It should be rewritten like this:
|
||||
</p>
|
||||
|
||||
<sample src="examples/MultilineStringLiteralGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Section 7.8.4. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @name Multi-line string literal
|
||||
* @description Multi-line string literals are non-standard and hard to read, and should be avoided.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/multi-line-string
|
||||
* @tags maintainability
|
||||
* external/cwe/cwe-758
|
||||
* @precision low
|
||||
* @deprecated Multi-line string literals are now a standard language feature. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from StringLiteral sl, Location l
|
||||
where
|
||||
l = sl.getLocation() and
|
||||
l.getStartLine() != l.getEndLine()
|
||||
select sl, "Avoid multi-line string literals."
|
||||
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Integer literals starting with the digit <code>0</code> may be interpreted as octal numbers by some platforms
|
||||
but not others, and thus should be avoided. This does not make a difference for the literal <code>0</code>
|
||||
itself.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
If the literal was meant to be octal, convert it to a decimal or hexadecimal number. Otherwise, remove
|
||||
the leading zero.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following example uses the literal <code>012</code>, which some platforms will interpret as an octal
|
||||
encoding of the decimal number <code>10</code>, while others will interpret it as the decimal number
|
||||
<code>12</code>. Depending on the desired interpretation, it should be replaced with either <code>10</code>
|
||||
or <code>12</code>.
|
||||
</p>
|
||||
|
||||
<sample src="examples/OctalLiteral.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Annex B.1.1. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* @name Octal literal
|
||||
* @description Octal numeric literals are a platform-specific extension and should not be used.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/octal-literal
|
||||
* @tags portability
|
||||
* external/cwe/cwe-758
|
||||
* @precision low
|
||||
* @deprecated This query is prone to false positives. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from NumberLiteral nl
|
||||
where nl.getRawValue().regexpMatch("0\\d+")
|
||||
select nl, "Do not use octal literals."
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
The ECMAScript standard defines a list of future keywords that should not be used as identifiers.
|
||||
While they may be accepted by current implementations, they may no longer be supported in the future,
|
||||
so it is best not to rely on them.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Rename the identifier in question.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following code snippet, <code>package</code> is used as a variable name. Since <code>package</code>
|
||||
is a future reserved word, the variable should be renamed, for instance to <code>pkg</code>.
|
||||
</p>
|
||||
|
||||
<sample src="examples/ReservedWords.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Section 7.6.1.2. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* @name Reserved word used as variable name
|
||||
* @description Future reserved words should not be used as variable names.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/use-of-reserved-word
|
||||
* @tags maintainability
|
||||
* language-features
|
||||
* @precision very-high
|
||||
* @deprecated This is no longer a problem with modern browsers. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from Identifier id
|
||||
where
|
||||
id
|
||||
.getName()
|
||||
.regexpMatch("class|const|enum|export|extends|import|super|implements|interface|let|package|private|protected|public|static|yield") and
|
||||
not exists(DotExpr de | id = de.getProperty()) and
|
||||
not exists(Property prop | id = prop.getNameExpr()) and
|
||||
// exclude JSX attribute names
|
||||
not exists(JSXElement e | id = e.getAnAttribute().getNameExpr())
|
||||
select id, "Identifier name is a reserved word."
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
The ECMAScript standard allows trailing commas in array and object literals which are ignored. However,
|
||||
older versions of Internet Explorer do not recognize this syntax. Moreover, it can lead to confusion
|
||||
when used in array literals, since spurious commas other than the last one are not ignored but give rise
|
||||
to additional undefined array elements. For these reasons, trailing commas should always be avoided.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Remove the trailing comma.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code snippet shows an object literal with a trailing comma, which should be removed.
|
||||
</p>
|
||||
|
||||
<sample src="examples/TrailingComma.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>Ecma International, <i>ECMAScript Language Definition</i>, 5.1 Edition, Sections 11.1.4 and 11.1.5. ECMA, 2011.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* @name Trailing comma in array or object expressions
|
||||
* @description Trailing commas in array and object expressions are interpreted differently
|
||||
* by different browsers and should be avoided.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/trailing-comma-in-array-or-object
|
||||
* @tags portability
|
||||
* external/cwe/cwe-758
|
||||
* @precision low
|
||||
* @deprecated This is no longer a problem with modern browsers. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/** An array or object expression. */
|
||||
class ArrayOrObjectExpr extends Expr {
|
||||
ArrayOrObjectExpr() {
|
||||
this instanceof ArrayExpr or
|
||||
this instanceof ObjectExpr
|
||||
}
|
||||
|
||||
/** Holds if this array or object expression has a trailing comma. */
|
||||
predicate hasTrailingComma() {
|
||||
this.(ArrayExpr).hasTrailingComma() or
|
||||
this.(ObjectExpr).hasTrailingComma()
|
||||
}
|
||||
|
||||
/** Gets a short description of this expression. */
|
||||
string getShortName() {
|
||||
if this instanceof ArrayExpr then result = "array expression" else result = "object expression"
|
||||
}
|
||||
}
|
||||
|
||||
from ArrayOrObjectExpr e
|
||||
where e.hasTrailingComma()
|
||||
select e.getLastToken().getPreviousToken(), "Trailing comma in " + e.getShortName() + "."
|
||||
@@ -1,51 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
On some platforms, the builtin function <code>parseInt</code> parses strings starting with the digit
|
||||
<code>0</code> as octal values (unless an explicit radix is provided). This can lead to unexpected
|
||||
results when parsing decimal numbers that may be zero-padded, such as dates.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Provide an explicit radix as the second parameter to <code>parseInt</code>.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following example, <code>parseInt</code> is used to convert the contents of a field in an HTML
|
||||
form to a number:
|
||||
</p>
|
||||
|
||||
<sample src="examples/ParseIntRadix.js" />
|
||||
|
||||
<p>
|
||||
Now assume that a user has entered a zero-padded decimal number, say <code>09</code>, into the form.
|
||||
Since the first digit is a zero, older versions of <code>parseInt</code> interpret this value as an
|
||||
octal number. When they then encounter <code>9</code> (which is not an octal digit), they will stop
|
||||
parsing and discard the rest of the string, returning the value <code>0</code>, which is probably not
|
||||
what was expected.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To avoid this problem, an explicit radix parameter should be parsed as follows:
|
||||
</p>
|
||||
|
||||
<sample src="examples/ParseIntRadixGood.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
|
||||
<li>D. Crockford, <i>JavaScript: The Good Parts</i>, Appendix A.7. O'Reilly, 2008.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @name Call to parseInt without radix
|
||||
* @description Calls to the 'parseInt' function should always specify a radix to avoid accidentally
|
||||
* parsing a number as octal.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @id js/parseint-without-radix
|
||||
* @tags reliability
|
||||
* maintainability
|
||||
* external/cwe/cwe-676
|
||||
* @precision very-high
|
||||
* @deprecated This is no longer a problem with modern browsers. Deprecated since 1.17.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
from DataFlow::CallNode parseInt
|
||||
where
|
||||
parseInt = DataFlow::globalVarRef("parseInt").getACall() and
|
||||
parseInt.getNumArgument() = 1
|
||||
select parseInt, "Missing radix parameter."
|
||||
@@ -1,7 +0,0 @@
|
||||
| builtinRedefined.js:1:1:1:4 | eval | Redefinition of eval. |
|
||||
| builtinRedefined.js:2:3:2:6 | eval | Redefinition of eval. |
|
||||
| builtinRedefined.js:3:5:3:8 | eval | Redefinition of eval. |
|
||||
| builtinRedefined.js:4:12:4:15 | eval | Redefinition of eval. |
|
||||
| builtinRedefined.js:5:18:5:21 | eval | Redefinition of eval. |
|
||||
| builtinRedefined.js:8:1:8:6 | Object | Redefinition of Object. |
|
||||
| builtinRedefined.js:10:12:10:20 | undefined | Redefinition of undefined. |
|
||||
@@ -1 +0,0 @@
|
||||
Declarations/BuiltinRedefined.ql
|
||||
@@ -1,14 +0,0 @@
|
||||
eval = 42;
|
||||
++eval;
|
||||
var eval;
|
||||
function x(eval) { }
|
||||
var y = function eval() { };
|
||||
eval("");
|
||||
|
||||
Object = function(){};
|
||||
|
||||
function f(undefined) {}
|
||||
(function f(undefined){}());
|
||||
|
||||
Date = this.Date;
|
||||
var Math = this.Math;
|
||||
@@ -1,3 +0,0 @@
|
||||
Object = function(){};
|
||||
|
||||
//semmle-extractor-options: --externs
|
||||
@@ -1 +0,0 @@
|
||||
| tst.js:6:5:6:28 | this.di ... \\n }; | dist should be added to the prototype object rather than to each instance. |
|
||||
@@ -1 +0,0 @@
|
||||
Declarations/InefficientMethodDefinition.ql
|
||||
@@ -1,53 +0,0 @@
|
||||
function Point(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// NOT OK
|
||||
this.dist = function() {
|
||||
return Math.sqrt(this.x*this.x + this.y*this.y);
|
||||
};
|
||||
|
||||
// OK
|
||||
this.getOriginalX = function() {
|
||||
return x;
|
||||
};
|
||||
|
||||
// OK
|
||||
this.getOriginalXGetter = function() {
|
||||
return function() {
|
||||
return x;
|
||||
};
|
||||
};
|
||||
|
||||
// OK
|
||||
this.getOtherOriginalXGetter = function() {
|
||||
function getter() {
|
||||
return x;
|
||||
}
|
||||
|
||||
return getter;
|
||||
};
|
||||
|
||||
if (x === 0)
|
||||
// OK
|
||||
this.dist = function() {
|
||||
return y;
|
||||
};
|
||||
|
||||
var o = {};
|
||||
// OK
|
||||
o.f = function() { return 23; };
|
||||
}
|
||||
|
||||
// OK
|
||||
var o = new(function() {
|
||||
this.f = function() { return 42 };
|
||||
});
|
||||
|
||||
// OK
|
||||
(function() {
|
||||
this.move = function(dx, dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
};
|
||||
}).call(Point.prototype);
|
||||
@@ -1,9 +0,0 @@
|
||||
| tst.js:1:1:1:11 | x % 2 === 1 | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:2:1:2:11 | x % 2 !== 1 | Test for evenness does not take negative numbers into account. |
|
||||
| tst.js:3:1:3:10 | x % 2 == 1 | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:4:1:4:10 | x % 2 != 1 | Test for evenness does not take negative numbers into account. |
|
||||
| tst.js:25:1:25:9 | x % 2 > 0 | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:29:1:29:17 | x % (2) === ((1)) | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:31:1:31:11 | 1 === x % 2 | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:43:1:43:11 | y % 2 === 1 | Test for oddness does not take negative numbers into account. |
|
||||
| tst.js:47:9:47:17 | i % 2 > 0 | Test for oddness does not take negative numbers into account. |
|
||||
@@ -1 +0,0 @@
|
||||
Expressions/BadParityCheck.ql
|
||||
@@ -1,48 +0,0 @@
|
||||
x % 2 === 1;
|
||||
x % 2 !== 1;
|
||||
x % 2 == 1;
|
||||
x % 2 != 1;
|
||||
x % 2 >= 1;
|
||||
x % 2 <= 1;
|
||||
x % 2 > 1;
|
||||
x % 2 < 1;
|
||||
|
||||
x % 2 === -1;
|
||||
x % 2 !== -1;
|
||||
x % 2 == -1;
|
||||
x % 2 != -1;
|
||||
x % 2 >= -1;
|
||||
x % 2 <= -1;
|
||||
x % 2 > -1;
|
||||
x % 2 < -1;
|
||||
|
||||
x % 2 === 0;
|
||||
x % 2 !== 0;
|
||||
x % 2 == 0;
|
||||
x % 2 != 0;
|
||||
x % 2 >= 0;
|
||||
x % 2 <= 0;
|
||||
x % 2 > 0;
|
||||
x % 2 < 0;
|
||||
|
||||
x % 3 === 1;
|
||||
x % (2) === ((1));
|
||||
2 % x == 1;
|
||||
1 === x % 2;
|
||||
|
||||
x = Math.random() > 0.5 ? -1 : 1;
|
||||
|
||||
// OK
|
||||
function printOdd(n) {
|
||||
for (var i=0; i<n; ++i)
|
||||
if (i % 2 == 1)
|
||||
console.log(i);
|
||||
}
|
||||
|
||||
// NOT OK
|
||||
y % 2 === 1;
|
||||
|
||||
// NOT OK
|
||||
function isEven(i) {
|
||||
return i % 2 > 0;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
| tst.js:9:1:9:5 | o.Foo | 'Foo' is mentioned only once; it may be a typo for 'foo'. |
|
||||
| tst.js:26:5:26:9 | iccID | 'iccID' is mentioned only once; it may be a typo for 'iccId'. |
|
||||
@@ -1 +0,0 @@
|
||||
Expressions/HapaxLegomenon.ql
|
||||
@@ -1,7 +0,0 @@
|
||||
var google;
|
||||
|
||||
google.maps.Marker;
|
||||
|
||||
google.maps.Bar = 23;
|
||||
|
||||
//semmle-extractor-options: --externs
|
||||
@@ -1,33 +0,0 @@
|
||||
/*properties Map*/
|
||||
|
||||
var o = {
|
||||
foo: function() {}
|
||||
};
|
||||
|
||||
o.foo();
|
||||
o.foo();
|
||||
o.Foo();
|
||||
|
||||
new google.maps.Map(document.getElementById("map"), mapOptions);
|
||||
[].map(function(){});
|
||||
[1, 2, 3].map(function(){});
|
||||
|
||||
new google.maps.Marker();
|
||||
google.maps.marker;
|
||||
google.maps.marker;
|
||||
|
||||
var q = { bar: 42 };
|
||||
q.bar;
|
||||
q.bar;
|
||||
|
||||
function tst(iccId) {
|
||||
iccId;
|
||||
iccId;
|
||||
iccID;
|
||||
}
|
||||
|
||||
/*property startsWith*/
|
||||
var o = { StartsWith: 42 };
|
||||
o.StartsWith;
|
||||
o.StartsWith;
|
||||
"hi".startsWith("h");
|
||||
@@ -1 +0,0 @@
|
||||
| tst.js:7:4:7:9 | @parma | Unknown tag type 'parma'. |
|
||||
@@ -1 +0,0 @@
|
||||
JSDoc/UnknownTagType.ql
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* A message.
|
||||
*
|
||||
* @constructor
|
||||
*
|
||||
* @param title
|
||||
* @parma text
|
||||
*/
|
||||
function Message(title, body) {
|
||||
this.title = title;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @modifies something
|
||||
*/
|
||||
function f() {}
|
||||
@@ -1,3 +0,0 @@
|
||||
| tst.js:2:1:2:13 | /* global x*/ | JSLint directives must not have whitespace characters before the directive name. |
|
||||
| tst.js:3:1:3:18 | /* global x,y: z*/ | JSLint directives must not have whitespace characters before the directive name. |
|
||||
| tst.js:16:1:98:2 | /* glob ... rue,\\n*/ | JSLint directives must not have whitespace characters before the directive name. |
|
||||
@@ -1 +0,0 @@
|
||||
JSLint/InvalidJSLintDirective.ql
|
||||
@@ -1,187 +0,0 @@
|
||||
// NOT OK
|
||||
/* global x*/
|
||||
/* global x,y: z*/
|
||||
|
||||
// OK: vacuous directives
|
||||
/* jslint */
|
||||
/* properties*/
|
||||
|
||||
// OK: not a directive
|
||||
/* jslint is popular. */
|
||||
|
||||
// OK: not a directive
|
||||
// global x
|
||||
|
||||
// NOT OK
|
||||
/* global angular: true,
|
||||
msie: true,
|
||||
jqLite: true,
|
||||
jQuery: true,
|
||||
slice: true,
|
||||
push: true,
|
||||
toString: true,
|
||||
ngMinErr: true,
|
||||
angularModule: true,
|
||||
nodeName_: true,
|
||||
uid: true,
|
||||
VALIDITY_STATE_PROPERTY: true,
|
||||
|
||||
lowercase: true,
|
||||
uppercase: true,
|
||||
manualLowercase: true,
|
||||
manualUppercase: true,
|
||||
nodeName_: true,
|
||||
isArrayLike: true,
|
||||
forEach: true,
|
||||
sortedKeys: true,
|
||||
forEachSorted: true,
|
||||
reverseParams: true,
|
||||
nextUid: true,
|
||||
setHashKey: true,
|
||||
extend: true,
|
||||
int: true,
|
||||
inherit: true,
|
||||
noop: true,
|
||||
identity: true,
|
||||
valueFn: true,
|
||||
isUndefined: true,
|
||||
isDefined: true,
|
||||
isObject: true,
|
||||
isString: true,
|
||||
isNumber: true,
|
||||
isDate: true,
|
||||
isArray: true,
|
||||
isFunction: true,
|
||||
isRegExp: true,
|
||||
isWindow: true,
|
||||
isScope: true,
|
||||
isFile: true,
|
||||
isBlob: true,
|
||||
isBoolean: true,
|
||||
isPromiseLike: true,
|
||||
trim: true,
|
||||
isElement: true,
|
||||
makeMap: true,
|
||||
map: true,
|
||||
size: true,
|
||||
includes: true,
|
||||
indexOf: true,
|
||||
arrayRemove: true,
|
||||
isLeafNode: true,
|
||||
copy: true,
|
||||
shallowCopy: true,
|
||||
equals: true,
|
||||
csp: true,
|
||||
concat: true,
|
||||
sliceArgs: true,
|
||||
bind: true,
|
||||
toJsonReplacer: true,
|
||||
toJson: true,
|
||||
fromJson: true,
|
||||
toBoolean: true,
|
||||
startingTag: true,
|
||||
tryDecodeURIComponent: true,
|
||||
parseKeyValue: true,
|
||||
toKeyValue: true,
|
||||
encodeUriSegment: true,
|
||||
encodeUriQuery: true,
|
||||
angularInit: true,
|
||||
bootstrap: true,
|
||||
snake_case: true,
|
||||
bindJQuery: true,
|
||||
assertArg: true,
|
||||
assertArgFn: true,
|
||||
assertNotHasOwnProperty: true,
|
||||
getter: true,
|
||||
getBlockElements: true,
|
||||
hasOwnProperty: true,
|
||||
*/
|
||||
|
||||
// OK: not a directive
|
||||
/*notadirective global x*/
|
||||
|
||||
// OK: not a directive
|
||||
/* global angular: true,
|
||||
msie: true,
|
||||
jqLite: true,
|
||||
jQuery: true,
|
||||
slice: true,
|
||||
push: true,
|
||||
toString: true,
|
||||
ngMinErr: true,
|
||||
angularModule: true,
|
||||
nodeName_: true,
|
||||
uid: true,
|
||||
VALIDITY_STATE_PROPERTY: true,
|
||||
|
||||
lowercase: true,
|
||||
uppercase: true,
|
||||
manualLowercase: true,
|
||||
manualUppercase: true,
|
||||
nodeName_: true,
|
||||
isArrayLike: true,
|
||||
forEach: true,
|
||||
sortedKeys: true,
|
||||
forEachSorted: true,
|
||||
reverseParams: true,
|
||||
nextUid: true,
|
||||
setHashKey: true,
|
||||
extend: true,
|
||||
int: true,
|
||||
inherit: true,
|
||||
noop: true,
|
||||
identity: true,
|
||||
valueFn: true,
|
||||
isUndefined: true,
|
||||
isDefined: true,
|
||||
isObject: true,
|
||||
isString: true,
|
||||
isNumber: true,
|
||||
isDate: true,
|
||||
isArray: true,
|
||||
isFunction: true,
|
||||
isRegExp: true,
|
||||
isWindow: true,
|
||||
isScope: true,
|
||||
isFile: true,
|
||||
isBlob: true,
|
||||
isBoolean: true,
|
||||
isPromiseLike: true,
|
||||
trim: true,
|
||||
isElement: true,
|
||||
makeMap: true,
|
||||
map: true,
|
||||
size: true,
|
||||
includes: true,
|
||||
indexOf: true,
|
||||
arrayRemove: true,
|
||||
isLeafNode: true,
|
||||
copy: true,
|
||||
shallowCopy: true,
|
||||
equals: true,
|
||||
csp: true,
|
||||
concat: true,
|
||||
sliceArgs: true,
|
||||
bind: true,
|
||||
toJsonReplacer: true,
|
||||
toJson: true,
|
||||
fromJson: true,
|
||||
toBoolean: true,
|
||||
startingTag: true,
|
||||
tryDecodeURIComponent: true,
|
||||
parseKeyValue: true,
|
||||
toKeyValue: true,
|
||||
encodeUriSegment: true,
|
||||
encodeUriQuery: true,
|
||||
angularInit: true,
|
||||
bootstrap: true,
|
||||
snake_case: true,
|
||||
bindJQuery: true,
|
||||
assertArg: true,
|
||||
assertArgFn: true,
|
||||
assertNotHasOwnProperty: true,
|
||||
getter: true,
|
||||
getBlockElements: true,
|
||||
hasOwnProperty: true,
|
||||
@@@
|
||||
*/
|
||||
@@ -1,3 +0,0 @@
|
||||
| tst.js:1:1:1:38 | /*jslin ... true */ | Malformed JSLint directive. |
|
||||
| tst.js:2:1:3:20 | /*jslin ... true */ | Malformed JSLint directive. |
|
||||
| tst.js:5:1:5:17 | /*global a:treu*/ | Malformed JSLint directive. |
|
||||
@@ -1 +0,0 @@
|
||||
JSLint/MalformedJSLintDirective.ql
|
||||
@@ -1,9 +0,0 @@
|
||||
/*jslint bitwise:true plusplus:true */
|
||||
/*jslint bitwise:true,
|
||||
* plusplus:true */
|
||||
/*jslint bitwise:true, plusplus:true */
|
||||
/*global a:treu*/
|
||||
/*properties */
|
||||
/*jslint forin: true, maxlen: 350 */
|
||||
/* global x*/
|
||||
/* global $*/
|
||||
@@ -1 +0,0 @@
|
||||
| tst.js:1:1:1:11 | <!-- NOT OK | Do not use HTML comments. |
|
||||
@@ -1 +0,0 @@
|
||||
LanguageFeatures/HTMLComments.ql
|
||||
@@ -1,3 +0,0 @@
|
||||
<!-- NOT OK
|
||||
// OK
|
||||
/* OK */
|
||||
@@ -1 +0,0 @@
|
||||
| multilineStringLiteral.js:2:9:7:38 | 'A rath ... e day.' | Avoid multi-line string literals. |
|
||||
@@ -1 +0,0 @@
|
||||
LanguageFeatures/MultilineStringLiteral.ql
|
||||
@@ -1,9 +0,0 @@
|
||||
function sayHello() {
|
||||
nok = 'A rather long string of English text, an error message \
|
||||
actually that just keeps going and going -- an error \
|
||||
message to make the Energizer bunny blush (right through \
|
||||
those Schwarzenegger shades)! Where was I? Oh yes, \
|
||||
you\'ve got an error and all the extraneous whitespace is \
|
||||
just gravy. Have a nice day.';
|
||||
ok = 'ok';
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
| tst.js:1:5:1:14 | implements | Identifier name is a reserved word. |
|
||||
| tst.js:1:17:1:25 | interface | Identifier name is a reserved word. |
|
||||
| tst.js:1:28:1:34 | package | Identifier name is a reserved word. |
|
||||
| tst.js:1:37:1:43 | private | Identifier name is a reserved word. |
|
||||
| tst.js:1:46:1:54 | protected | Identifier name is a reserved word. |
|
||||
| tst.js:1:57:1:62 | public | Identifier name is a reserved word. |
|
||||
| tst.js:1:65:1:70 | static | Identifier name is a reserved word. |
|
||||
@@ -1 +0,0 @@
|
||||
LanguageFeatures/ReservedWords.ql
|
||||
@@ -1 +0,0 @@
|
||||
var div = <div class="highlight">Hi!</div>;
|
||||
@@ -1,5 +0,0 @@
|
||||
var implements, interface, package, private, protected, public, static; // NOT OK
|
||||
|
||||
({
|
||||
implements: true // OK
|
||||
})
|
||||
@@ -1,2 +0,0 @@
|
||||
| tst.js:1:9:1:9 | , | Trailing comma in object expression. |
|
||||
| tst.js:2:6:2:6 | , | Trailing comma in array expression. |
|
||||
@@ -1 +0,0 @@
|
||||
LanguageFeatures/TrailingComma.ql
|
||||
@@ -1,2 +0,0 @@
|
||||
({ x: 42, }) // NOT OK
|
||||
([ 23, ]); // NOT OK
|
||||
@@ -1 +0,0 @@
|
||||
| tst.js:1:1:1:24 | parseIn ... .value) | Missing radix parameter. |
|
||||
@@ -1 +0,0 @@
|
||||
StandardLibrary/ParseIntRadix.ql
|
||||
@@ -1,8 +0,0 @@
|
||||
parseInt(form.day.value);
|
||||
parseInt(form.day.value, 10);
|
||||
o.parseInt(s);
|
||||
|
||||
function f(parseInt, s) {
|
||||
parseInt();
|
||||
parseInt(s, 10);
|
||||
}
|
||||
Reference in New Issue
Block a user