[前][次][番号順一覧][スレッド一覧]

ruby-changes:55881

From: Nobuyoshi <ko1@a...>
Date: Wed, 29 May 2019 00:07:06 +0900 (JST)
Subject: [ruby-changes:55881] Nobuyoshi Nakada: c730c25354 (trunk): parse.y: warn escaped whitespace

https://git.ruby-lang.org/ruby.git/commit/?id=c730c25354

From c730c25354a18e99b9147c30ecc8f986d6a172f1 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 28 May 2019 21:39:13 +0900
Subject: parse.y: warn escaped whitespace

* parse.y (warn_space_char_code): warn whitespace characters
  escaped with meta/control prefix.

diff --git a/parse.y b/parse.y
index a218819..091efa9 100644
--- a/parse.y
+++ b/parse.y
@@ -6139,6 +6139,36 @@ tok_hex(struct parser_params *p, size_t *numlen) https://github.com/ruby/ruby/blob/trunk/parse.y#L6139
 #define tokcopy(p, n) memcpy(tokspace(p, n), (p)->lex.pcur - (n), (n))
 
 static int
+escaped_control_code(int c)
+{
+    int c2 = 0;
+    switch (c) {
+      case ' ':
+	c2 = 's';
+	break;
+      case '\n':
+	c2 = 'n';
+	break;
+      case '\t':
+	c2 = 't';
+	break;
+      case '\v':
+	c2 = 'v';
+	break;
+      case '\r':
+	c2 = 'r';
+	break;
+      case '\f':
+	c2 = 'f';
+	break;
+    }
+    return c2;
+}
+
+#define WARN_SPACE_CHAR(c, prefix) \
+    rb_warn1("invalid character syntax; use "prefix"\\%c", WARN_I(c2))
+
+static int
 tokadd_codepoint(struct parser_params *p, rb_encoding **encp,
 		 int regexp_literal, int wide)
 {
@@ -6290,6 +6320,16 @@ read_escape(struct parser_params *p, int flags, rb_encoding **encp) https://github.com/ruby/ruby/blob/trunk/parse.y#L6320
 	}
 	else if (c == -1 || !ISASCII(c)) goto eof;
 	else {
+	    int c2 = escaped_control_code(c);
+	    if (c2) {
+		if (ISCNTRL(c) || !(flags & ESCAPE_CONTROL)) {
+		    WARN_SPACE_CHAR(c2, "\\M-");
+		}
+		else {
+		    WARN_SPACE_CHAR(c2, "\\C-\\M-");
+		}
+	    }
+	    else if (ISCNTRL(c)) goto eof;
 	    return ((c & 0xff) | 0x80);
 	}
 
@@ -6306,6 +6346,28 @@ read_escape(struct parser_params *p, int flags, rb_encoding **encp) https://github.com/ruby/ruby/blob/trunk/parse.y#L6346
 	else if (c == '?')
 	    return 0177;
 	else if (c == -1 || !ISASCII(c)) goto eof;
+	else {
+	    int c2 = escaped_control_code(c);
+	    if (c2) {
+		if (ISCNTRL(c)) {
+		    if (flags & ESCAPE_META) {
+			WARN_SPACE_CHAR(c2, "\\M-");
+		    }
+		    else {
+			WARN_SPACE_CHAR(c2, "");
+		    }
+		}
+		else {
+		    if (flags & ESCAPE_META) {
+			WARN_SPACE_CHAR(c2, "\\M-\\C-");
+		    }
+		    else {
+			WARN_SPACE_CHAR(c2, "\\C-");
+		    }
+		}
+	    }
+	    else if (ISCNTRL(c)) goto eof;
+	}
 	return c & 0x9f;
 
       eof:
@@ -8009,29 +8071,9 @@ parse_qmark(struct parser_params *p, int space_seen) https://github.com/ruby/ruby/blob/trunk/parse.y#L8071
     }
     if (rb_enc_isspace(c, p->enc)) {
 	if (!IS_ARG()) {
-	    int c2 = 0;
-	    switch (c) {
-	      case ' ':
-		c2 = 's';
-		break;
-	      case '\n':
-		c2 = 'n';
-		break;
-	      case '\t':
-		c2 = 't';
-		break;
-	      case '\v':
-		c2 = 'v';
-		break;
-	      case '\r':
-		c2 = 'r';
-		break;
-	      case '\f':
-		c2 = 'f';
-		break;
-	    }
+	    int c2 = escaped_control_code(c);
 	    if (c2) {
-		rb_warn1("invalid character syntax; use ?\\%c", WARN_I(c2));
+		WARN_SPACE_CHAR(c2, "?");
 	    }
 	}
       ternary:
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index ff40474..3f5acde 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -45,6 +45,7 @@ class TestRubyLiteral < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_literal.rb#L45
     assert_equal "A", ?A
     assert_instance_of String, ?\n
     assert_equal "\n", ?\n
+    assert_equal " ", ?\s
     assert_equal " ", ?\   # space
     assert_equal '', ''
     assert_equal 'string', 'string'
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 11a77ba..fca8d74 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -548,6 +548,19 @@ class TestParse < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L548
 
     assert_equal("\x81", eval('"\C-\M-a"'))
     assert_equal("\177", eval('"\c?"'))
+
+    assert_warning(/use \\C-\\s/) {assert_equal("\x00", eval('"\C- "'))}
+    assert_warning(/use \\M-\\s/) {assert_equal("\xa0", eval('"\M- "'))}
+    assert_warning(/use \\M-\\C-\\s/) {assert_equal("\x80", eval('"\M-\C- "'))}
+    assert_warning(/use \\C-\\M-\\s/) {assert_equal("\x80", eval('"\C-\M- "'))}
+    assert_warning(/use \\t/) {assert_equal("\x09", eval("\"\\C-\t\""))}
+    assert_warning(/use \\M-\\t/) {assert_equal("\x89", eval("\"\\M-\t\""))}
+    assert_warning(/use \\M-\\t/) {assert_equal("\x89", eval("\"\\M-\\C-\t\""))}
+    assert_warning(/use \\M-\\t/) {assert_equal("\x89", eval("\"\\C-\\M-\t\""))}
+    assert_syntax_error("\"\\C-\x01\"", 'Invalid escape character syntax')
+    assert_syntax_error("\"\\M-\x01\"", 'Invalid escape character syntax')
+    assert_syntax_error("\"\\M-\\C-\x01\"", 'Invalid escape character syntax')
+    assert_syntax_error("\"\\C-\\M-\x01\"", 'Invalid escape character syntax')
   end
 
   def test_question
@@ -565,6 +578,19 @@ class TestParse < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L578
     assert_equal("\u{1234}", eval('?\u1234'))
     e = assert_syntax_error('"#{?\u123}"', 'invalid Unicode escape')
     assert_not_match(/end-of-input/, e.message)
+
+    assert_warning(/use ?\\C-\\s/) {assert_equal("\x00", eval('?\C- '))}
+    assert_warning(/use ?\\M-\\s/) {assert_equal("\xa0", eval('?\M- '))}
+    assert_warning(/use ?\\M-\\C-\\s/) {assert_equal("\x80", eval('?\M-\C- '))}
+    assert_warning(/use ?\\C-\\M-\\s/) {assert_equal("\x80", eval('?\C-\M- '))}
+    assert_warning(/use ?\\t/) {assert_equal("\x09", eval("?\\C-\t"))}
+    assert_warning(/use ?\\M-\\t/) {assert_equal("\x89", eval("?\\M-\t"))}
+    assert_warning(/use ?\\M-\\t/) {assert_equal("\x89", eval("?\\M-\\C-\t"))}
+    assert_warning(/use ?\\M-\\t/) {assert_equal("\x89", eval("?\\C-\\M-\t"))}
+    assert_syntax_error("?\\C-\x01", 'Invalid escape character syntax')
+    assert_syntax_error("?\\M-\x01", 'Invalid escape character syntax')
+    assert_syntax_error("?\\M-\\C-\x01", 'Invalid escape character syntax')
+    assert_syntax_error("?\\C-\\M-\x01", 'Invalid escape character syntax')
   end
 
   def test_percent
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]