Commit 4b92b0f8 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Clear scope_snapshot_ upon parser destruction to avoid use-after-(recent)free

|scope_snapshot_| might not have been cleared if there was a parser error between setting
the snapshot and consuming it. Explicitly clear it at the end of parsing for that case.
Otherwise Scope::Snapshot's destructor will possibly write into the already freed zone.

Bug: chromium:909976
Change-Id: I8469d11f04e7f71528be5cba5663c652cd7eacb2
Reviewed-on: https://chromium-review.googlesource.com/c/1354880
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57938}
parent bb22e322
...@@ -128,7 +128,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -128,7 +128,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
Snapshot() Snapshot()
: outer_scope_and_calls_eval_(nullptr, false), : outer_scope_and_calls_eval_(nullptr, false),
top_unresolved_(), top_unresolved_(),
top_local_() {} top_local_() {
DCHECK(IsCleared());
}
inline explicit Snapshot(Scope* scope); inline explicit Snapshot(Scope* scope);
~Snapshot() { ~Snapshot() {
...@@ -168,7 +170,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -168,7 +170,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
return outer_scope_and_calls_eval_.GetPointer() == nullptr; return outer_scope_and_calls_eval_.GetPointer() == nullptr;
} }
private:
void Clear() { void Clear() {
outer_scope_and_calls_eval_.SetPointer(nullptr); outer_scope_and_calls_eval_.SetPointer(nullptr);
#ifdef DEBUG #ifdef DEBUG
...@@ -179,6 +180,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -179,6 +180,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
#endif #endif
} }
private:
// During tracking calls_eval caches whether the outer scope called eval. // During tracking calls_eval caches whether the outer scope called eval.
// Upon move assignment we store whether the new inner scope calls eval into // Upon move assignment we store whether the new inner scope calls eval into
// the move target calls_eval bit, and restore calls eval on the outer // the move target calls_eval bit, and restore calls eval on the outer
......
...@@ -263,12 +263,12 @@ class ParserBase { ...@@ -263,12 +263,12 @@ class ParserBase {
pointer_buffer_.reserve(128); pointer_buffer_.reserve(128);
} }
~ParserBase() { scope_snapshot_.Clear(); }
#define ALLOW_ACCESSORS(name) \ #define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \ bool allow_##name() const { return allow_##name##_; } \
void set_allow_##name(bool allow) { allow_##name##_ = allow; } void set_allow_##name(bool allow) { allow_##name##_ = allow; }
void set_rewritable_length(int i) { rewritable_length_ = i; }
ALLOW_ACCESSORS(natives); ALLOW_ACCESSORS(natives);
ALLOW_ACCESSORS(harmony_public_fields); ALLOW_ACCESSORS(harmony_public_fields);
ALLOW_ACCESSORS(harmony_static_fields); ALLOW_ACCESSORS(harmony_static_fields);
...@@ -279,6 +279,7 @@ class ParserBase { ...@@ -279,6 +279,7 @@ class ParserBase {
#undef ALLOW_ACCESSORS #undef ALLOW_ACCESSORS
void set_rewritable_length(int i) { rewritable_length_ = i; }
V8_INLINE bool has_error() const { return scanner()->has_parser_error(); } V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
bool allow_harmony_numeric_separator() const { bool allow_harmony_numeric_separator() const {
return scanner()->allow_harmony_numeric_separator(); return scanner()->allow_harmony_numeric_separator();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment