bool parser::parse_string(context& ctx, string_type& value, IteratorType& ch, IteratorType end) { ctx.clear(); if (!check_char(ctx, '"', ch, end)) { return false; } while (ch != end) { if (std::iscntrl(*ch)) { return false; } switch (*ch) { case '"': { // The string ends. ++ch; value = ctx.str(); return true; } case '\\': { // An escape character was provided. ++ch; if (ch == end) { return false; } switch (*ch) { case '"': ctx.push_char('"'); ++ch; break; case '\\': ctx.push_char('\\'); ++ch; break; case '/': ctx.push_char('/'); ++ch; break; case 'b': ctx.push_char('\b'); ++ch; break; case 'n': ctx.push_char('\n'); ++ch; break; case 'f': ctx.push_char('\f'); ++ch; break; case 'r': ctx.push_char('\r'); ++ch; break; case 't': ctx.push_char('\t'); ++ch; break; case 'u': { ++ch; uint16_t codepoint = 0x0000; for (size_t i = 0; i < 4; ++i) { if (ch == end) { return false; } if (!std::isxdigit(*ch)) { return false; } codepoint *= 16; codepoint += xdigit_to_int(*ch); ++ch; } ctx.push_codepoint(codepoint); break; } default: return false; } break; } default: { ctx.push_char(*ch); ++ch; } } } return false; }
bool parser::parse_number(context& ctx, number_type& value, IteratorType& ch, IteratorType end) { ctx.clear(); // Check if the number is negative if (ch != end) { if (*ch == '-') { ctx.push_char(*ch); ++ch; } } if (ch == end) { return false; } switch (*ch) { case '0': ctx.push_char(*ch); ++ch; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ctx.push_char(*ch); ++ch; while ((ch != end) && std::isdigit(*ch)) { ctx.push_char(*ch); ++ch; } break; } // Check for a period if (ch != end) { if (*ch == '.') { ctx.push_char(*ch); ++ch; while ((ch != end) && std::isdigit(*ch)) { ctx.push_char(*ch); ++ch; } } } // Check for an exponent if (ch != end) { if ((*ch == 'e') || (*ch == 'E')) { ctx.push_char(*ch); ++ch; if (ch == end) { return false; } switch (*ch) { case '-': ctx.push_char(*ch); ++ch; break; case '+': ctx.push_char(*ch); ++ch; break; } if (ch == end) { return false; } while ((ch != end) && std::isdigit(*ch)) { ctx.push_char(*ch); ++ch; } } } if (!ctx.get_number(value)) { return false; } return true; }
// Reset the taint status of registers and memory void TaintTracker::resetTaint(context &delta) { delta.clear(); memory.clear(); }