Don't track len separately

This commit is contained in:
2025-05-14 14:12:44 -04:00
parent 9876afafb2
commit 35ca9e4562

View File

@@ -223,7 +223,7 @@ namespace {
// treats numbers as [0-9.]+. May stack overflow on deeply nested json documents // treats numbers as [0-9.]+. May stack overflow on deeply nested json documents
struct Parser1 { struct Parser1 {
Parser1(char *buf, int len, const Callbacks *callbacks, void *data) Parser1(char *buf, int len, const Callbacks *callbacks, void *data)
: buf(buf), len(len), callbacks(callbacks), data(data) {} : buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
// Returns false to reject // Returns false to reject
[[nodiscard]] bool parse() { return parse_element(); } [[nodiscard]] bool parse() { return parse_element(); }
@@ -235,29 +235,29 @@ struct Parser1 {
private: private:
char *buf; char *buf;
int len; char *bufEnd;
const Callbacks *const callbacks; const Callbacks *const callbacks;
void *const data; void *const data;
int len() const { return bufEnd - buf; }
// Helpers // Helpers
void maybeSkipWs() { void maybeSkipWs() {
int leadingWs = leadingWhitespaceCount(buf, len); int leadingWs = leadingWhitespaceCount(buf, len());
buf += leadingWs; buf += leadingWs;
len -= leadingWs;
} }
bool parseLiteral(const char *literal) { bool parseLiteral(const char *literal) {
const int litLen = strlen(literal); const int litLen = strlen(literal);
if (len < litLen) { if (len() < litLen) {
return false; return false;
} }
len -= litLen;
return memcmp(std::exchange(buf, buf + litLen), literal, litLen) == 0; return memcmp(std::exchange(buf, buf + litLen), literal, litLen) == 0;
} }
// functions corresponding to productions // functions corresponding to productions
bool parse_element() { bool parse_element() {
maybeSkipWs(); maybeSkipWs();
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if (*buf == '{') { if (*buf == '{') {
@@ -299,7 +299,7 @@ private:
} }
callbacks->on_begin_object(data); callbacks->on_begin_object(data);
maybeSkipWs(); maybeSkipWs();
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if (*buf != '}') { if (*buf != '}') {
@@ -318,7 +318,7 @@ private:
if (!parse_member()) { if (!parse_member()) {
return false; return false;
} }
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if (*buf == ',') { if (*buf == ',') {
@@ -351,7 +351,7 @@ private:
} }
callbacks->on_begin_array(data); callbacks->on_begin_array(data);
maybeSkipWs(); maybeSkipWs();
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if (*buf != ']') { if (*buf != ']') {
@@ -371,7 +371,7 @@ private:
if (!parse_element()) { if (!parse_element()) {
return false; return false;
} }
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if (*buf == ',') { if (*buf == ',') {
@@ -388,14 +388,13 @@ private:
if (!parseLiteral("\"")) { if (!parseLiteral("\"")) {
return false; return false;
} }
auto *result = (char *)memchr(buf, '"', len); auto *result = (char *)memchr(buf, '"', len());
if (result == nullptr) { if (result == nullptr) {
return false; return false;
} }
int stringLen = result - buf; int stringLen = result - buf;
callbacks->on_string_data(data, buf, stringLen); callbacks->on_string_data(data, buf, stringLen);
buf += stringLen; buf += stringLen;
len -= stringLen;
if (!parseLiteral("\"")) { if (!parseLiteral("\"")) {
return false; return false;
} }
@@ -407,12 +406,11 @@ private:
callbacks->on_begin_number(data); callbacks->on_begin_number(data);
char *const bufBefore = buf; char *const bufBefore = buf;
for (;;) { for (;;) {
if (len == 0) { if (len() == 0) {
return false; return false;
} }
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) { if ('0' <= *buf && *buf <= '9' || (*buf == '.')) {
++buf; ++buf;
--len;
} else { } else {
break; break;
} }
@@ -464,7 +462,7 @@ private:
// [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory. // [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory.
struct Parser2 { struct Parser2 {
Parser2(char *buf, int len, const Callbacks *callbacks, void *data) Parser2(char *buf, int len, const Callbacks *callbacks, void *data)
: buf(buf), len(len), callbacks(callbacks), data(data) {} : buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
// Returns false to reject // Returns false to reject
[[nodiscard]] bool parse() { [[nodiscard]] bool parse() {
@@ -484,17 +482,16 @@ struct Parser2 {
private: private:
// Helpers // Helpers
void maybeSkipWs() { void maybeSkipWs() {
int leadingWs = leadingWhitespaceCount(buf, len); int leadingWs = leadingWhitespaceCount(buf, len());
// printf("ws: %d\n", leadingWs);
buf += leadingWs; buf += leadingWs;
len -= leadingWs;
} }
bool parseLiteral(const char *literal) { bool parseLiteral(const char *literal) {
const int litLen = strlen(literal); const int litLen = strlen(literal);
if (len < litLen) { if (len() < litLen) {
return false; return false;
} }
if (memcmp(buf, literal, litLen) == 0) { if (memcmp(buf, literal, litLen) == 0) {
len -= litLen;
buf += litLen; buf += litLen;
return true; return true;
} }
@@ -502,16 +499,14 @@ private:
} }
bool parse_number() { bool parse_number() {
char *const bufBefore = buf; char *const bufBefore = buf;
if (len == 0 || !('0' <= *buf && *buf <= '9' || (*buf == '.'))) { if (len() == 0 || !('0' <= *buf && *buf <= '9' || (*buf == '.'))) {
return false; return false;
} }
callbacks->on_begin_number(data); callbacks->on_begin_number(data);
++buf; ++buf;
--len;
for (;;) { for (;;) {
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) { if ('0' <= *buf && *buf <= '9' || (*buf == '.')) {
++buf; ++buf;
--len;
} else { } else {
break; break;
} }
@@ -528,14 +523,13 @@ private:
return false; return false;
} }
callbacks->on_begin_string(data); callbacks->on_begin_string(data);
auto *result = (char *)memchr(buf, '"', len); auto *result = (char *)memchr(buf, '"', len());
if (result == nullptr) { if (result == nullptr) {
return false; return false;
} }
int stringLen = result - buf; int stringLen = result - buf;
callbacks->on_string_data(data, buf, stringLen); callbacks->on_string_data(data, buf, stringLen);
buf += stringLen; buf += stringLen;
len -= stringLen;
if (!parseLiteral("\"")) { if (!parseLiteral("\"")) {
return false; return false;
} }
@@ -650,7 +644,8 @@ private:
}; };
char *buf; char *buf;
int len; char *bufEnd;
int len() { return bufEnd - buf; }
const Callbacks *const callbacks; const Callbacks *const callbacks;
void *const data; void *const data;
Symbol stack[kMaxStackSize]; Symbol stack[kMaxStackSize];