From 04422d716cf226b5e8a6c11306e07adbde26fd67 Mon Sep 17 00:00:00 2001 From: Evgeny Bobkin Date: Wed, 17 Jul 2013 17:16:06 +0200 Subject: [PATCH] Add support for the \uXXXX escape sequence An additional checks to validate the escape sequences \xYY and \uYYYY were added, where Y represents a hex digit. https://bugzilla.gnome.org/show_bug.cgi?id=704709 --- tests/Makefile.am | 1 + tests/basic-types/escape-chars.vala | 17 ++++++++ vala/valascanner.vala | 63 ++++++++++++++++++++++++++--- 3 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 tests/basic-types/escape-chars.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index 8a0df29c3..b84ee0411 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,6 +16,7 @@ TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' L TESTS = \ basic-types/integers.vala \ + basic-types/escape-chars.vala \ basic-types/floats.vala \ basic-types/strings.vala \ basic-types/arrays.vala \ diff --git a/tests/basic-types/escape-chars.vala b/tests/basic-types/escape-chars.vala new file mode 100644 index 000000000..6ff1662a6 --- /dev/null +++ b/tests/basic-types/escape-chars.vala @@ -0,0 +1,17 @@ +void test_x_escape_chars () { + string s = "Copyright \xc2\xa9"; + + assert (s == "Copyright ©"); +} + +void test_u_escape_chars () { + string s = "Copyright \u00a9"; + + assert (s == "Copyright ©"); +} + +void main () { + // Test case for bug report 704709 + test_x_escape_chars (); + test_u_escape_chars (); +} diff --git a/vala/valascanner.vala b/vala/valascanner.vala index ba4736966..ab1628cc0 100644 --- a/vala/valascanner.vala +++ b/vala/valascanner.vala @@ -212,14 +212,31 @@ public class Vala.Scanner { current++; token_length_in_chars++; break; + case 'u': + // u escape character has four hex digits + current++; + token_length_in_chars++; + int digit_length; + for (digit_length = 0; digit_length < 4 && current < end && current[0].isxdigit (); digit_length++) { + current++; + token_length_in_chars++; + } + if (digit_length != 4) { + Report.error (get_source_reference (token_length_in_chars), "\\u requires four hex digits"); + } + break; case 'x': - // hexadecimal escape character + // hexadecimal escape character requires two hex digits current++; token_length_in_chars++; - while (current < end && current[0].isxdigit ()) { + int digit_length; + for (digit_length = 0; digit_length < 2 && current < end && current[0].isxdigit (); digit_length++) { current++; token_length_in_chars++; } + if (digit_length != 2) { + Report.error (get_source_reference (token_length_in_chars), "\\x requires two hex digits"); + } break; default: Report.error (get_source_reference (token_length_in_chars), "invalid escape sequence"); @@ -693,14 +710,31 @@ public class Vala.Scanner { current++; token_length_in_chars++; break; + case 'u': + // u escape character has four hex digits + current++; + token_length_in_chars++; + int digit_length; + for (digit_length = 0; digit_length < 4 && current < end && current[0].isxdigit (); digit_length++) { + current++; + token_length_in_chars++; + } + if (digit_length != 4) { + Report.error (get_source_reference (token_length_in_chars), "\\u requires four hex digits"); + } + break; case 'x': - // hexadecimal escape character + // hexadecimal escape character requires two hex digits current++; token_length_in_chars++; - while (current < end && current[0].isxdigit ()) { + int digit_length; + for (digit_length = 0; digit_length < 2 && current < end && current[0].isxdigit (); digit_length++) { current++; token_length_in_chars++; } + if (digit_length != 2) { + Report.error (get_source_reference (token_length_in_chars), "\\x requires two hex digits"); + } break; default: Report.error (get_source_reference (token_length_in_chars), "invalid escape sequence"); @@ -1110,14 +1144,31 @@ public class Vala.Scanner { current++; token_length_in_chars++; break; + case 'u': + // u escape character has four hex digits + current++; + token_length_in_chars++; + int digit_length; + for (digit_length = 0; digit_length < 4 && current < end && current[0].isxdigit (); digit_length++) { + current++; + token_length_in_chars++; + } + if (digit_length != 4) { + Report.error (get_source_reference (token_length_in_chars), "\\u requires four hex digits"); + } + break; case 'x': - // hexadecimal escape character + // hexadecimal escape character requires two hex digits current++; token_length_in_chars++; - while (current < end && current[0].isxdigit ()) { + int digit_length; + for (digit_length = 0; digit_length < 2 && current < end && current[0].isxdigit (); digit_length++) { current++; token_length_in_chars++; } + if (digit_length != 2) { + Report.error (get_source_reference (token_length_in_chars), "\\x requires two hex digits"); + } break; default: Report.error (get_source_reference (token_length_in_chars), "invalid escape sequence"); -- 2.47.2