diff --git a/buf/validate/internal/lib/ipv6.cc b/buf/validate/internal/lib/ipv6.cc index 3a5a62b..1c3d074 100644 --- a/buf/validate/internal/lib/ipv6.cc +++ b/buf/validate/internal/lib/ipv6.cc @@ -46,7 +46,7 @@ struct IPv6Parser : ParserCommon, public IPv6Prefix { if (str.length() < minLength) { return false; } - return str[1] == '.' || str[2] == '.' || str[3] == '.'; + return str[0] != ':' && (str[1] == '.' || str[2] == '.' || str[3] == '.'); } bool parseDotted() { @@ -71,28 +71,22 @@ struct IPv6Parser : ParserCommon, public IPv6Prefix { int index = 0; bool doubleColonFound = false; uint16_t value; - enum : uint8_t { - Initial, - Hexadecatet, - Separator, - DoubleColon, - } state = Initial; while (index < hexadecatets_count) { - if ((state == Separator || state == DoubleColon) && - (doubleColonFound || index == hexadecatets_count - 2) && checkDotted()) { + if ((doubleColonFound || index == hexadecatets_count - 2) && checkDotted()) { if (!parseDotted()) { return false; } b <<= 32; index += 2; break; - } else if (state != Hexadecatet && parseHexadecimalHexadecatet(value)) { - state = Hexadecatet; + } else if (parseHexadecimalHexadecatet(value)) { b <<= 16; b |= value; index++; - } else if (state != Separator && consumeSequence<':', ':'>()) { - state = DoubleColon; + } else if (consumeSequence<':', ':'>()) { + if (consume>()) { + return false; + } if (index > hexadecatets_count - 1 || doubleColonFound) { return false; } @@ -102,14 +96,14 @@ struct IPv6Parser : ParserCommon, public IPv6Prefix { // This ensures that we can't have more than 7 hexadecatets when there's // a double-colon, even though we don't actually process a hexadecatet. index++; - } else if (state == Hexadecatet && consume>()) { - state = Separator; - } else { - // Unable to match anything: this is the end. - if (state != Hexadecatet && state != DoubleColon) { - // Ending on a separator is invalid. + } else if (consume>()) { + if (index == 0 || str.empty()) { + // Can not start or end on a single colon. return false; } + continue; + } else { + // Unable to match anything: this is the end. break; } } diff --git a/buf/validate/internal/lib/uri.cc b/buf/validate/internal/lib/uri.cc index 85e8137..88a4b7f 100644 --- a/buf/validate/internal/lib/uri.cc +++ b/buf/validate/internal/lib/uri.cc @@ -202,34 +202,32 @@ struct UriParser : ParserCommon { const size_t hexadecatets_count = 8; int index = 0; bool doubleColonFound = false; - enum : uint8_t { Initial, Hexadecatet, Separator, DoubleColon } state = Initial; while (index < hexadecatets_count) { - if ((state == Separator || state == DoubleColon) && - (doubleColonFound || index == hexadecatets_count - 2) && - str.length() >= std::char_traits::length("0.0.0.0") && + if ((doubleColonFound || index == hexadecatets_count - 2) && + str.length() >= std::char_traits::length("0.0.0.0") && str[0] != ':' && (str[1] == '.' || str[2] == '.' || str[3] == '.')) { uint8_t _; return parseDecimalOctet(_) && consume>() && // parseDecimalOctet(_) && consume>() && // parseDecimalOctet(_) && consume>() && // parseDecimalOctet(_); - } else if (uint16_t _; state != Hexadecatet && parseHexadecimalHexadecatet(_)) { - state = Hexadecatet; + } else if (uint16_t _; parseHexadecimalHexadecatet(_)) { index++; - } else if (state != Separator && consumeSequence<':', ':'>()) { - state = DoubleColon; - if (index++ > hexadecatets_count - 1 || doubleColonFound) { + } else if (consumeSequence<':', ':'>()) { + if (consume>() || index++ > hexadecatets_count - 1 || doubleColonFound) { return false; } doubleColonFound = true; - } else if (state == Hexadecatet && consume>()) { - state = Separator; + } else if (consume>()) { + if (index == 0 || str.empty()) { + return false; + } + continue; } else { break; } } - return (state == Hexadecatet || state == DoubleColon) && - (doubleColonFound || index == hexadecatets_count) && + return (doubleColonFound || index == hexadecatets_count) && (!consumeSequence<'%', '2', '5'>() || consumeZoneId()); }