diff --git a/src/parser3.h b/src/parser3.h index 335fb09..4fd54f6 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -245,7 +245,9 @@ inline PRESERVE_NONE WeaselJsonStatus scan_string(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -349,7 +351,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -375,7 +379,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -399,7 +405,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -420,7 +428,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -444,7 +454,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self, char *buf, char *bufEnd) { - assert(bufEnd - buf != 0); + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -468,6 +480,9 @@ inline int32_t read4_hex(const char *buf) { inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (auto s = scan_string(self, buf, bufEnd)) { return s; } @@ -495,8 +510,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf, if (0xd800 <= codepoint && codepoint <= 0xdfff) { // utf-16 surrogate int32_t codepoint2 = read4_hex(buf + 2); - if (!(buf[0] == '\\' && buf[1] == 'u' && codepoint2 >= 0)) - [[unlikely]] { + if (!(buf[0] == '\\' && buf[1] == 'u' && 0xdc00 <= codepoint2 && + codepoint2 <= 0xdfff)) [[unlikely]] { return WeaselJson_REJECT; } codepoint = @@ -550,6 +565,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_string_following_escape(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } assert(self->strDfa.accept()); switch (*buf) { case '"': @@ -578,6 +596,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_string_following_escape(Parser3 *self, inline PRESERVE_NONE WeaselJsonStatus t_hex(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } auto hexVal = tables.hex[uint8_t(*buf)]; if (hexVal < 0) [[unlikely]] { return WeaselJson_REJECT; @@ -591,6 +612,9 @@ inline PRESERVE_NONE WeaselJsonStatus t_hex(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus t_hex2(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } auto hexVal = tables.hex[uint8_t(*buf)]; if (hexVal < 0) [[unlikely]] { return WeaselJson_REJECT; @@ -655,6 +679,9 @@ inline PRESERVE_NONE WeaselJsonStatus t_hex2(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus t_hex3(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } auto hexVal = tables.hex[uint8_t(*buf)]; if (hexVal < 0) [[unlikely]] { return WeaselJson_REJECT; @@ -703,6 +730,9 @@ inline PRESERVE_NONE WeaselJsonStatus t_hex3(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_true(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (*buf == 'e') { ++buf; self->pop(); @@ -715,6 +745,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_true(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_false(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (*buf == 'e') { ++buf; self->pop(); @@ -727,6 +760,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_false(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_null(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if (*buf == 'l') { ++buf; self->pop(); @@ -740,8 +776,10 @@ inline PRESERVE_NONE WeaselJsonStatus n_null(Parser3 *self, char *buf, template inline PRESERVE_NONE WeaselJsonStatus singleChar(Parser3 *self, char *buf, char *bufEnd) { + if (buf == bufEnd) [[unlikely]] { + return WeaselJson_REJECT; + } if constexpr (kSkipWhitespace) { - assert(bufEnd - buf != 0); if (auto s = skipWhitespace(buf, bufEnd)) { return s; } @@ -823,16 +861,9 @@ constexpr inline struct ContinuationTable { symbolNames[T_HEX3] = "t_hex3"; symbolNames[T_EOF] = "t_eof"; symbolNames[T_BACKSLASH] = "singleChar<'\\'>"; - - // All others can assume that there's at least one byte when they're - // called - acceptsEmptyString[N_NUMBER] = true; - acceptsEmptyString[N_WHITESPACE] = true; - acceptsEmptyString[T_EOF] = true; } Continuation continuations[N_SYMBOL_COUNT]{}; const char *symbolNames[N_SYMBOL_COUNT]{}; - bool acceptsEmptyString[N_SYMBOL_COUNT]{}; } symbolTables; inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self, @@ -876,9 +907,6 @@ inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self, } return WeaselJson_AGAIN; } - if (!symbolTables.acceptsEmptyString[self->top()]) [[unlikely]] { - return WeaselJson_REJECT; - } } // printf("%s\n", symbolTables.symbolNames[self->top()]); MUSTTAIL return symbolTables.continuations[self->top()](self, buf, bufEnd);