diff options
-rw-r--r-- | Base/usr/share/man/man5/Shell.md | 3 | ||||
-rw-r--r-- | Userland/Shell/Parser.cpp | 12 | ||||
-rw-r--r-- | Userland/Shell/Parser.h | 3 |
3 files changed, 16 insertions, 2 deletions
diff --git a/Base/usr/share/man/man5/Shell.md b/Base/usr/share/man/man5/Shell.md index 5815a73321..bb3254d266 100644 --- a/Base/usr/share/man/man5/Shell.md +++ b/Base/usr/share/man/man5/Shell.md @@ -477,7 +477,8 @@ string :: '"' dquoted_string_inner '"' dquoted_string_inner :: '\' . dquoted_string_inner? {concat} | variable dquoted_string_inner? {compose} | . dquoted_string_inner? - | '\' 'x' digit digit dquoted_string_inner? + | '\' 'x' xdigit*2 dquoted_string_inner? + | '\' 'u' xdigit*8 dquoted_string_inner? | '\' [abefrn] dquoted_string_inner? variable :: variable_ref slice? diff --git a/Userland/Shell/Parser.cpp b/Userland/Shell/Parser.cpp index 410b633eda..93d4f3b5fd 100644 --- a/Userland/Shell/Parser.cpp +++ b/Userland/Shell/Parser.cpp @@ -1315,6 +1315,18 @@ RefPtr<AST::Node> Parser::parse_doublequoted_string_inner() builder.append(to_byte(first_nibble, second_nibble)); break; } + case 'u': { + if (m_input.length() <= m_offset + 8) + break; + size_t counter = 8; + auto chars = consume_while([&](auto) { return counter-- > 0; }); + if (auto number = AK::StringUtils::convert_to_uint_from_hex(chars); number.has_value()) + builder.append(Utf32View { &number.value(), 1 }); + else + builder.append(chars); + + break; + } case 'a': builder.append('\a'); break; diff --git a/Userland/Shell/Parser.h b/Userland/Shell/Parser.h index 306c8517d1..bb2fb9d794 100644 --- a/Userland/Shell/Parser.h +++ b/Userland/Shell/Parser.h @@ -265,7 +265,8 @@ string :: '"' dquoted_string_inner '"' dquoted_string_inner :: '\' . dquoted_string_inner? {concat} | variable dquoted_string_inner? {compose} | . dquoted_string_inner? - | '\' 'x' digit digit dquoted_string_inner? + | '\' 'x' xdigit*2 dquoted_string_inner? + | '\' 'u' xdigit*8 dquoted_string_inner? | '\' [abefrn] dquoted_string_inner? variable :: variable_ref slice? |