From b45ed217c61cd69eee2eafd9dbf5798520685538 Mon Sep 17 00:00:00 2001 From: mdempsky Date: Tue, 31 Mar 2015 16:58:20 -0700 Subject: [PATCH] tools/gn: disallow non-canonical integer literals In most languages familiar to Chromium developers (e.g., C++, JavaScript, Python, Java, Go, Bash, Perl, Ruby), a leading 0 in an integer literal indicates an octal number. For example, "010" and "-010" represent 8 and -8, respectively. GN doesn't have any use for octal integer literals, so reject integers with leading zeros to avoid confusion rather than interpreting them as decimal values. While here, "-0" isn't useful either since it's equivalent to "0", so reject that too. No Chromium BUILD.gn files are affected by this change. Review URL: https://codereview.chromium.org/1038233002 Cr-Commit-Position: refs/heads/master@{#323142} --- tools/gn/parse_tree.cc | 10 +++++++++- tools/gn/parse_tree_unittest.cc | 36 ++++++++++++++++++++++++++++++++++++ tools/gn/parser.cc | 2 ++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc index f5897065548f..5e5b9ea01b71 100644 --- a/tools/gn/parse_tree.cc +++ b/tools/gn/parse_tree.cc @@ -634,8 +634,16 @@ Value LiteralNode::Execute(Scope* scope, Err* err) const { case Token::FALSE_TOKEN: return Value(this, false); case Token::INTEGER: { + base::StringPiece s = value_.value(); + if ((s.starts_with("0") && s.size() > 1) || s.starts_with("-0")) { + if (s == "-0") + *err = MakeErrorDescribing("Negative zero doesn't make sense"); + else + *err = MakeErrorDescribing("Leading zeros not allowed"); + return Value(); + } int64 result_int; - if (!base::StringToInt64(value_.value(), &result_int)) { + if (!base::StringToInt64(s, &result_int)) { *err = MakeErrorDescribing("This does not look like an integer"); return Value(); } diff --git a/tools/gn/parse_tree_unittest.cc b/tools/gn/parse_tree_unittest.cc index 827f3d54a5ce..29a0faf36f95 100644 --- a/tools/gn/parse_tree_unittest.cc +++ b/tools/gn/parse_tree_unittest.cc @@ -212,3 +212,39 @@ TEST(ParseTree, SortRangeExtraction) { EXPECT_EQ(3u, ranges[0].end); } } + +TEST(ParseTree, Integers) { + static const char* const kGood[] = { + "0", + "10", + "-54321", + "9223372036854775807", // INT64_MAX + "-9223372036854775808", // INT64_MIN + }; + for (auto s : kGood) { + TestParseInput input(std::string("x = ") + s); + EXPECT_FALSE(input.has_error()); + + TestWithScope setup; + Err err; + input.parsed()->Execute(setup.scope(), &err); + EXPECT_FALSE(err.has_error()); + } + + static const char* const kBad[] = { + "-0", + "010", + "-010", + "9223372036854775808", // INT64_MAX + 1 + "-9223372036854775809", // INT64_MIN - 1 + }; + for (auto s : kBad) { + TestParseInput input(std::string("x = ") + s); + EXPECT_FALSE(input.has_error()); + + TestWithScope setup; + Err err; + input.parsed()->Execute(setup.scope(), &err); + EXPECT_TRUE(err.has_error()); + } +} diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc index 1fa432e3a806..05aab74227bc 100644 --- a/tools/gn/parser.cc +++ b/tools/gn/parser.cc @@ -49,6 +49,8 @@ const char kGrammar_Help[] = "\n" " integer = [ \"-\" ] digit { digit } .\n" "\n" + " Leading zeros and negative zero are disallowed.\n" + "\n" "String literals\n" "\n" " A string literal represents a string value consisting of the quoted\n" -- 2.11.4.GIT