Skip to content

Commit

Permalink
Scanner for json-parser's internal state.
Browse files Browse the repository at this point in the history
Summary:
We have a surprise-check in the JSON parser loop, to catch
heap-ooms from huge json blobs. When a GC triggers here,
we must scan the parser's state-stack.

Reviewed By: ricklavoie

Differential Revision: D2807258

fb-gh-sync-id: b8e704f921a794d84e3b80841c390fe58a53027a
  • Loading branch information
edwinsmith authored and hhvm-bot committed Jan 6, 2016
1 parent dadcb01 commit e030612
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
10 changes: 10 additions & 0 deletions hphp/runtime/ext/json/JSON_parser.cpp
Expand Up @@ -615,6 +615,7 @@ bool JSON_parser(Variant &z, const char *p, int length, bool const assoc,
json->stack[i].key.reset();
json->stack[i].val.unset();
}
json->mark = -1;
};

json->mark = json->top = -1;
Expand Down Expand Up @@ -970,6 +971,15 @@ bool JSON_parser(Variant &z, const char *p, int length, bool const assoc,
return false;
}

void json_parser_scan(IMarker& mark) {
if (s_json_parser.isNull()) return;
auto json = s_json_parser.get();
if (json->mark < 0 || json->stack.empty()) return;
for (int i = 0; i <= json->mark; ++i) {
mark(json->stack[i].key);
mark(json->stack[i].val);
}
}
}

#endif /* HAVE_JSONC */
2 changes: 2 additions & 0 deletions hphp/runtime/ext/json/JSON_parser.h
Expand Up @@ -24,11 +24,13 @@ namespace HPHP {

struct StringBuffer;
struct Variant;
struct IMarker;

void utf16_to_utf8(StringBuffer& buf, unsigned short utf16);
bool JSON_parser(Variant& z, const char *p, int length,
bool assoc, int depth, int64_t options);
void json_parser_init(); // called at request-init
void json_parser_scan(IMarker&);

enum json_error_codes {
JSON_ERROR_NONE = 0,
Expand Down
8 changes: 7 additions & 1 deletion hphp/runtime/ext/json/ext_json.cpp
Expand Up @@ -258,7 +258,13 @@ class JsonExtension final : public Extension {
loadSystemlib();
}

void requestInit() override { json_parser_init(); }
void requestInit() override {
json_parser_init();
}

void vscan(IMarker& mark) const override {
json_parser_scan(mark);
}

} s_json_extension;

Expand Down

0 comments on commit e030612

Please sign in to comment.