Fix handling of Unicode BOMs in JSONReader.

Because |char| is signed, the upper bits of the BOM bytes were getting 
interpreted as the sign bit. Cast to |uint8| to preserve them for proper
comparison.

BUG=119975
TEST=Try to install the Gmail extension. Do not get JSON error when unpacking.

Review URL: http://codereview.chromium.org/9860035

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129373 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: b09b083fef7460e5b407b9b0ea4b38dc77ccce42
diff --git a/base/base.gyp b/base/base.gyp
index 08461d7..02c8585 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -536,6 +536,7 @@
             # TODO(maruel): Revisit the support for this at all and list each
             # individual test files instead.
             'data/file_util_unittest/',
+            'data/json/bom_feff.json',
             '--',
             # Wraps base_unittests under xvfb.
             '<(DEPTH)/testing/xvfb.py',
diff --git a/base/json/json_reader.cc b/base/json/json_reader.cc
index 31eecb4..348e471 100644
--- a/base/json/json_reader.cc
+++ b/base/json/json_reader.cc
@@ -163,8 +163,9 @@
   // or <0xEF 0xBB 0xBF>, advance the start position to avoid the
   // JSONReader::BuildValue() function from mis-treating a Unicode BOM as an
   // invalid character and returning NULL.
-  if (json.size() >= 3 && start_pos_[0] == 0xEF &&
-      start_pos_[1] == 0xBB && start_pos_[2] == 0xBF) {
+  if (json.size() >= 3 && static_cast<uint8>(start_pos_[0]) == 0xEF &&
+      static_cast<uint8>(start_pos_[1]) == 0xBB &&
+      static_cast<uint8>(start_pos_[2]) == 0xBF) {
     start_pos_ += 3;
   }
 
diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
index 5900781..467bf4d 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -4,12 +4,15 @@
 
 #include "base/json/json_reader.h"
 
-#include "testing/gtest/include/gtest/gtest.h"
+#include "base/base_paths.h"
+#include "base/file_util.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
 #include "base/string_piece.h"
 #include "base/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
@@ -500,6 +503,23 @@
   EXPECT_FALSE(root.get());
 }
 
+TEST(JSONReaderTest, ReadFromFile) {
+  FilePath path;
+  ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path));
+  path = path.Append(FILE_PATH_LITERAL("base"))
+             .Append(FILE_PATH_LITERAL("data"))
+             .Append(FILE_PATH_LITERAL("json"));
+
+  std::string input;
+  ASSERT_TRUE(file_util::ReadFileToString(
+      path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input));
+
+  JSONReader reader;
+  scoped_ptr<Value> root(reader.JsonToValue(input, false, false));
+  ASSERT_TRUE(root.get()) << reader.GetErrorMessage();
+  EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
+}
+
 TEST(JSONReaderTest, ErrorMessages) {
   // Error strings should not be modified in case of success.
   std::string error_message;