fix: improve hashtag span validation and enhance test coverage for edge cases

This commit is contained in:
Terry Carr committed 2026-10-10 21:56:21 +01:00
1 parent 4ed3fdb52c
commit c5042b71d3
2 files changed
+32 -4

No files matched your search

+9 -2
View File
@@ -29,12 +29,18 @@ namespace ChatHashtag
inline bool isHexColor(const char *text, int start, int end)
{
const int length = end - start;
if (length != 3 && length != 4 && length != 6 && length != 8)
if (length != 6 && length != 8)
return false;
bool colorLike = false;
for (int offset = start; offset < end; ++offset)
{
if (!isxdigit((unsigned char)text[offset]))
return false;
return true;
if (isdigit((unsigned char)text[offset]) ||
(text[offset] >= 'A' && text[offset] <= 'F'))
colorLike = true;
}
return colorLike;
}
inline bool span(const char *text, int from, int *start, int *end)
@@ -81,6 +87,7 @@ namespace ChatHashtag
}
if (finish == offset + 1 || finish - offset >= 32 ||
isdigit((unsigned char)text[offset + 1]) ||
text[offset + 1] == '_' || text[offset + 1] == '-' ||
isHexColor(text, offset + 1, finish))
continue;
*start = offset;
+23 -2
View File
@@ -26,6 +26,19 @@ int main() {
assert(!ChatHashtag::span("#caf\xC3", 0, &start, &end));
assert(!ChatHashtag::span("#1", 0, &start, &end));
assert(!ChatHashtag::span("#1channel", 0, &start, &end));
assert(!ChatHashtag::span("#_", 0, &start, &end));
assert(!ChatHashtag::span("#-", 0, &start, &end));
assert(!ChatHashtag::span("#___", 0, &start, &end));
assert(!ChatHashtag::span("#---", 0, &start, &end));
assert(!ChatHashtag::span("#_-_", 0, &start, &end));
assert(!ChatHashtag::span("#_42", 0, &start, &end));
assert(!ChatHashtag::span("#-42", 0, &start, &end));
assert(!ChatHashtag::span("#_mesh", 0, &start, &end));
assert(!ChatHashtag::span("#-mesh", 0, &start, &end));
const std::string separators_then_tag = "#_ #- #_-_ #_42 #-42 #mesh";
assert(ChatHashtag::span(separators_then_tag.c_str(), 0, &start, &end));
assert(separators_then_tag.substr(start, end - start) == "#mesh");
assert(!ChatHashtag::span(separators_then_tag.c_str(), end, &start, &end));
assert(ChatHashtag::span("#channel1", 0, &start, &end));
const std::string trailing_hyphen = "#mesh-";
assert(ChatHashtag::span(trailing_hyphen.c_str(), 0, &start, &end));
@@ -39,11 +52,19 @@ int main() {
const std::string underscored = "#mesh_channel";
assert(ChatHashtag::span(underscored.c_str(), 0, &start, &end));
assert(underscored.substr(start, end - start) == "#mesh_channel");
assert(!ChatHashtag::span("#FFF", 0, &start, &end));
assert(!ChatHashtag::span("#FFFF", 0, &start, &end));
assert(ChatHashtag::span("#FFF", 0, &start, &end));
assert(ChatHashtag::span("#FFFF", 0, &start, &end));
assert(ChatHashtag::span("#beef", 0, &start, &end));
assert(ChatHashtag::span("#cafe", 0, &start, &end));
assert(ChatHashtag::span("#abcdef", 0, &start, &end));
assert(ChatHashtag::span("#deadbeef", 0, &start, &end));
assert(!ChatHashtag::span("#FFFFFF", 0, &start, &end));
assert(!ChatHashtag::span("#FF0000", 0, &start, &end));
assert(!ChatHashtag::span("#FFFFFFFF", 0, &start, &end));
assert(!ChatHashtag::span("#abcDef", 0, &start, &end));
assert(!ChatHashtag::span("#ff0000", 0, &start, &end));
assert(!ChatHashtag::span("#abcdef12", 0, &start, &end));
assert(ChatHashtag::span("#mesh12", 0, &start, &end));
assert(ChatHashtag::span("#cable", 0, &start, &end));
std::string long_tag = "#";
for (int count = 0; count < 15; ++count)