From ee8d2f50b77ea9f9f2b241f8e2bcbff8d68db327 Mon Sep 17 00:00:00 2001 From: Niketin Date: Sat, 10 May 2025 14:34:36 +0300 Subject: [PATCH] pattern/bencode: Various fixes (#393) * Fix bencode dictionary When parsing a bencode dictionary, the end character 'e' was never consumed. This caused a misinterpretation of the character as struct Value of an unknown type 'e'. * Fix bencode list A list was not included in the Value's parsing logic so it may have been mistakenly parsed as a string. * Fix std::ctype::isprint not including space The space character, 0x20, is considered as a printable character in ASCII and in >=C89. Adding it to the range of std::ctype::isprint also fixes other std::ctype functions that use it. * Fix bencode byte string formatting Byte strings do not render nicely in pattern data's value column if they contain non-printable characters. This commit makes the value of byte strings to be surrounded by quotation marks, and renders a warning text without quotation marks if the byte string contains non-printable characters. --- includes/std/ctype.pat | 2 +- patterns/bencode.hexpat | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/includes/std/ctype.pat b/includes/std/ctype.pat index 30f1881..82f49b9 100644 --- a/includes/std/ctype.pat +++ b/includes/std/ctype.pat @@ -85,7 +85,7 @@ namespace auto std::ctype { @return True if `c` is part of this range, false otherwise */ fn isprint(char c) { - return c >= '0' && c <= '~'; + return c >= ' ' && c <= '~'; }; /** diff --git a/patterns/bencode.hexpat b/patterns/bencode.hexpat index 070aab9..9f66ba7 100644 --- a/patterns/bencode.hexpat +++ b/patterns/bencode.hexpat @@ -38,10 +38,15 @@ namespace bencode { ASCIIDecimal length; char separator [[hidden]]; char value[length]; - } [[sealed, format("bencode::format_string"), transform("bencode::format_string")]]; + } [[sealed, format("bencode::format_string")]]; fn format_string(String string) { - return string.value; + for (u64 i = 0, i < string.length, i = i + 1) { + if (!std::ctype::isprint(string.value[i])) { + return "Contains non-printable characters"; + } + } + return std::format("\"{}\"", string.value); }; using Bencode; @@ -57,6 +62,10 @@ namespace bencode { if (type == Type::Dictionary) { DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')]; + char end; + } else if (type == Type::List) { + Value entry[while(std::mem::read_unsigned($, 1) != 'e')]; + char end; } else if (type == Type::Integer) { ASCIIDecimal value; char end;