Invocation of non-function¶
ID: js/call-to-non-callableKind: problemSecurity severity: Severity: errorPrecision: highTags: - quality - reliability - correctness - external/cwe/cwe-476Query suites: - javascript-security-and-quality.qls
Click to see the query in the CodeQL repository
Attempting to invoke a non-function (that is, a primitive value or an object) will cause an exception at runtime. This applies both to calls usingnew and normal calls.
Recommendation¶
Carefully inspect the invocation in question. If the problem was not detected during testing, this could either be because the invocation is in dead code, or because it is not covered by a test. In the former case, delete the dead code in question. In the latter case, consider adding a new test.
Example¶
In the following example, functionprocessResponse accepts an argumentresponse, and, depending on the value of propertyresponse.status, does one of two things: ifresponse.status is 200, it invokes a functionprocessResponseText (not shown), and if that function returns anerror value, it throws that value as an exception; otherwise, it invokeserror to log the value ofresponse.status.
functionerror(msg){console.log(msg);}functionprocessResponse(response){if(response.status===200){varerror=processResponseText(response.responseText);if(error)throwerror;}else{error("Unexpected response status "+response.status);}}
Note that due to JavaScript’s scoping rules,error in the “else” branch actually refers to theerror variable declared in the “then” branch (and not the global function of the same name). Since that variable is alwaysundefined in the “else” branch, attempting to invoke it will result in an exception at runtime.
To fix this problem,error could be turned into alet-bound variable to avoid the accidental name capture:
functionerror(msg){console.log(msg);}functionprocessResponse(response){if(response.status===200){leterror=processResponseText(response.responseText);if(error)throwerror;}else{error("Unexpected response status "+response.status);}}
Alternatively, if ECMAScript 5 compatibility is desired, theerror variable could be renamed instead, as in this example:
functionerror(msg){console.log(msg);}functionprocessResponse(response){if(response.status===200){varerr=processResponseText(response.responseText);if(err)throwerr;}else{error("Unexpected response status "+response.status);}}
References¶
Mozilla Developer Network:Calling functions.
Common Weakness Enumeration:CWE-476.