Open
Bug 1258379
Opened 9 years ago
Updated 2 years ago
[Static Analysis][Dereference before null check] In function Parser<ParseHandler>::bindVar
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
NEW
Tracking | Status | |
---|---|---|
firefox48 | --- | affected |
People
(Reporter: andi, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: coverity, Whiteboard: CID 1357072 )
Attachments
(2 files)
(deleted),
text/x-review-board-request
|
Details | |
(deleted),
patch
|
shu
:
review+
|
Details | Diff | Splinter Review |
The Static Analysis tool Coverity added that variable |last| is dereferenced before it is null checked leading to a possible null pointer derererence:
>> DefinitionNode last = pc->decls().lookupLast(name);
>> Definition::Kind lastKind = parser->handler.getDefinitionKind(last);
>> if (last && lastKind != Definition::VAR && lastKind != Definition::ARG) {
>> parser->handler.setFlag(parser->handler.getDefinitionNode(last), PND_CLOSED);
>>
>> Node synthesizedVarName = parser->newName(name);
>> if (!synthesizedVarName)
>> return false;
>> if (!pc->define(parser->tokenStream, name, synthesizedVarName, Definition::VAR,
>> /* declaringVarInCatchBody = */ true))
>> {
>> return false;
>> }
>> }
looking throug code i'm not convinced that |last| will always be a valid pointer, so i propose checked the validity of |last| before dereferencing it.
Reporter | ||
Comment 1•9 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/41411/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/41411/
Attachment #8732864 -
Flags: review?(jorendorff)
Comment 3•9 years ago
|
||
Comment on attachment 8732864 [details]
MozReview Request: Bug 1258379 - prevent null pointer derefence on |last|. r?jorendorff
https://reviewboard.mozilla.org/r/41411/#review37913
Declining review here - there's a better way. I'll whip up a patch and r?shu.
::: js/src/frontend/Parser.cpp:4100
(Diff revision 1)
> DefinitionList::Range defs = pc->decls().lookupMulti(name);
> MOZ_ASSERT_IF(stmt, !defs.empty());
>
> if (defs.empty())
> return pc->define(parser->tokenStream, name, pn, Definition::VAR);
>
This if-statement ensures that if we proceed, there is an entry in `pc->decls()` for `name` and therefore the lookup below can't miss. So I think the correct fix is to reuse `defs` rather than redoing the lookup.
::: js/src/frontend/Parser.cpp:4105
(Diff revision 1)
>
> // ES6 Annex B.3.5 allows for var declarations inside catch blocks with
> // the same name as the catch parameter.
> bool nameIsCatchParam = stmt && stmt->type == StmtType::CATCH;
> bool declaredVarInCatchBody = false;
> if (nameIsCatchParam && !data->isForOf && !HasOuterLexicalBinding(pc, stmt, name)) {
Attachment #8732864 -
Flags: review?(jorendorff)
Comment 4•9 years ago
|
||
Attachment #8732960 -
Flags: review?(shu)
Updated•9 years ago
|
Assignee: bogdan.postelnicu → jorendorff
Status: NEW → ASSIGNED
Comment 5•9 years ago
|
||
Reusing defs turns out to be a huge pain, so I changed it to assert instead of testing `last`. This should satisfy Coverity.
Comment 6•9 years ago
|
||
Comment on attachment 8732960 [details] [diff] [review]
Silence Coverity warning about a missing nullcheck in Parser<FPH>::bindVar()
Review of attachment 8732960 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/frontend/ParseMaps.h
@@ +472,5 @@
> /* Return the definition at the tail of the chain for |atom|. */
> DefinitionNode lookupLast(JSAtom* atom) const {
> MOZ_ASSERT(map);
> DefinitionList::Range range = lookupMulti(atom);
> + MOZ_ASSERT(!range.empty());
In the one use of this method in Parser.cpp, the range can never be empty. As a general purpose method though, it can very well be empty. Please move the assertion that dn is not null to Parser.cpp. Does that satisfy Coverity?
Attachment #8732960 -
Flags: review?(shu) → review+
Comment 7•9 years ago
|
||
There are three uses of this method in Parser.cpp, and in each case it's used only when a previous lookup (often lookupFirst) already found a binding, so the answer can't be null.
I'll leave the method as "general purpose", as requested... arguably, though, if there's ever a fourth call site for this method something has gone horribly wrong. :)
Comment 8•2 years ago
|
||
The bug assignee didn't login in Bugzilla in the last 7 months, so the assignee is being reset.
Assignee: jorendorff → nobody
Status: ASSIGNED → NEW
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•