summaryrefslogtreecommitdiff
path: root/chromium/third_party/jsoncpp
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2014-03-18 13:16:26 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-20 15:55:39 +0100
commit3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch)
tree92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/third_party/jsoncpp
parente90d7c4b152c56919d963987e2503f9909a666d2 (diff)
downloadqtwebengine-chromium-3f0f86b0caed75241fa71c95a5d73bc0164348c5.tar.gz
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies needed on Windows. Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42 Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu> Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/third_party/jsoncpp')
-rw-r--r--chromium/third_party/jsoncpp/README.chromium2
-rw-r--r--chromium/third_party/jsoncpp/jsoncpp.gyp33
-rw-r--r--chromium/third_party/jsoncpp/jsoncpp.gypi38
-rw-r--r--chromium/third_party/jsoncpp/jsoncpp_untrusted.gyp34
-rw-r--r--chromium/third_party/jsoncpp/overrides/src/lib_json/json_reader.cpp928
-rw-r--r--chromium/third_party/jsoncpp/overrides/src/lib_json/json_value.cpp10
6 files changed, 1012 insertions, 33 deletions
diff --git a/chromium/third_party/jsoncpp/README.chromium b/chromium/third_party/jsoncpp/README.chromium
index 6d87f6d953c..c2cb7d54a82 100644
--- a/chromium/third_party/jsoncpp/README.chromium
+++ b/chromium/third_party/jsoncpp/README.chromium
@@ -6,5 +6,5 @@ License File: LICENSE
Security Critical: yes
Description:
-The libjingle/webrtc uses jsoncpp for signaling message serialization and deserialization.
+The libjingle/webrtc/liblouis_nacl uses jsoncpp for signaling message serialization and deserialization.
diff --git a/chromium/third_party/jsoncpp/jsoncpp.gyp b/chromium/third_party/jsoncpp/jsoncpp.gyp
index 1395f94bbf0..ffb4eb3743b 100644
--- a/chromium/third_party/jsoncpp/jsoncpp.gyp
+++ b/chromium/third_party/jsoncpp/jsoncpp.gyp
@@ -3,40 +3,13 @@
# found in the LICENSE file.
{
+ 'includes': [
+ 'jsoncpp.gypi',
+ ],
'targets': [
{
'target_name': 'jsoncpp',
'type': 'static_library',
- 'defines': [
- 'JSON_USE_EXCEPTION=0',
- ],
- 'sources': [
- 'source/include/json/assertions.h',
- 'source/include/json/autolink.h',
- 'source/include/json/config.h',
- 'source/include/json/features.h',
- 'source/include/json/forwards.h',
- 'source/include/json/json.h',
- 'source/include/json/reader.h',
- 'overrides/include/json/value.h',
- 'source/include/json/writer.h',
- 'source/src/lib_json/json_batchallocator.h',
- 'source/src/lib_json/json_reader.cpp',
- 'source/src/lib_json/json_tool.h',
- 'overrides/src/lib_json/json_value.cpp',
- 'source/src/lib_json/json_writer.cpp',
- ],
- 'include_dirs': [
- 'overrides/include/',
- 'source/include/',
- 'source/src/lib_json/',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- 'overrides/include/',
- 'source/include/',
- ],
- },
},
],
}
diff --git a/chromium/third_party/jsoncpp/jsoncpp.gypi b/chromium/third_party/jsoncpp/jsoncpp.gypi
new file mode 100644
index 00000000000..3ce61e1fe0b
--- /dev/null
+++ b/chromium/third_party/jsoncpp/jsoncpp.gypi
@@ -0,0 +1,38 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'target_defaults': {
+ 'defines': [
+ 'JSON_USE_EXCEPTION=0',
+ ],
+ 'sources': [
+ 'source/include/json/assertions.h',
+ 'source/include/json/autolink.h',
+ 'source/include/json/config.h',
+ 'source/include/json/features.h',
+ 'source/include/json/forwards.h',
+ 'source/include/json/json.h',
+ 'source/include/json/reader.h',
+ 'overrides/include/json/value.h',
+ 'source/include/json/writer.h',
+ 'source/src/lib_json/json_batchallocator.h',
+ 'overrides/src/lib_json/json_reader.cpp',
+ 'source/src/lib_json/json_tool.h',
+ 'overrides/src/lib_json/json_value.cpp',
+ 'source/src/lib_json/json_writer.cpp',
+ ],
+ 'include_dirs': [
+ 'overrides/include/',
+ 'source/include/',
+ 'source/src/lib_json/',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ 'overrides/include/',
+ 'source/include/',
+ ],
+ },
+ },
+}
diff --git a/chromium/third_party/jsoncpp/jsoncpp_untrusted.gyp b/chromium/third_party/jsoncpp/jsoncpp_untrusted.gyp
new file mode 100644
index 00000000000..88537bf2acc
--- /dev/null
+++ b/chromium/third_party/jsoncpp/jsoncpp_untrusted.gyp
@@ -0,0 +1,34 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'includes': [
+ '../../build/common_untrusted.gypi',
+ 'jsoncpp.gypi',
+ ],
+ 'conditions': [
+ ['disable_nacl==0 and disable_nacl_untrusted==0', {
+ 'targets': [
+ {
+ 'target_name': 'jsoncpp_untrusted',
+ 'type': 'none',
+ 'variables': {
+ 'nacl_untrusted_build': 1,
+ 'nlib_target': 'libjsoncpp_untrusted.a',
+ 'build_newlib': 1,
+ },
+ 'gcc_compile_flags': [
+ # Turn off optimizations based on strict aliasing
+ # because of the workaround at
+ # overrides/src/lib_json/json_value.cpp:38.
+ '-fno-strict-aliasing',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
+ ],
+ },
+ ],
+ }],
+ ],
+}
diff --git a/chromium/third_party/jsoncpp/overrides/src/lib_json/json_reader.cpp b/chromium/third_party/jsoncpp/overrides/src/lib_json/json_reader.cpp
new file mode 100644
index 00000000000..1bc7429993b
--- /dev/null
+++ b/chromium/third_party/jsoncpp/overrides/src/lib_json/json_reader.cpp
@@ -0,0 +1,928 @@
+// Copyright 2007-2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+# include <json/assertions.h>
+# include <json/reader.h>
+# include <json/value.h>
+# include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <utility>
+#include <cstdio>
+#include <cassert>
+#include <cstring>
+#include <stdexcept>
+#ifdef __pnacl__
+// This file uses the following headers (at least in Reader::parse), but
+// the upstream version doesn't include them because iostream pulls in
+// static initializers. This breaks the PNaCl build because it uses
+// libc++ which declares getline in <string> (as per the C++ standard)
+// but defines it in <iostream>. The code therefore fails linking, which
+// these includes fix.
+#include <string>
+#include <iostream>
+#endif
+
+#if _MSC_VER >= 1400 // VC++ 8.0
+#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
+#endif
+
+namespace Json {
+
+// Implementation of class Features
+// ////////////////////////////////
+
+Features::Features()
+ : allowComments_( true )
+ , strictRoot_( false )
+{
+}
+
+
+Features
+Features::all()
+{
+ return Features();
+}
+
+
+Features
+Features::strictMode()
+{
+ Features features;
+ features.allowComments_ = false;
+ features.strictRoot_ = true;
+ return features;
+}
+
+// Implementation of class Reader
+// ////////////////////////////////
+
+
+static inline bool
+in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 )
+{
+ return c == c1 || c == c2 || c == c3 || c == c4;
+}
+
+static inline bool
+in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 )
+{
+ return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
+}
+
+
+static bool
+containsNewLine( Reader::Location begin,
+ Reader::Location end )
+{
+ for ( ;begin < end; ++begin )
+ if ( *begin == '\n' || *begin == '\r' )
+ return true;
+ return false;
+}
+
+
+// Class Reader
+// //////////////////////////////////////////////////////////////////
+
+Reader::Reader()
+ : errors_(),
+ document_(),
+ begin_(),
+ end_(),
+ current_(),
+ lastValueEnd_(),
+ lastValue_(),
+ commentsBefore_(),
+ features_( Features::all() ),
+ collectComments_()
+{
+}
+
+
+Reader::Reader( const Features &features )
+ : errors_(),
+ document_(),
+ begin_(),
+ end_(),
+ current_(),
+ lastValueEnd_(),
+ lastValue_(),
+ commentsBefore_(),
+ features_( features ),
+ collectComments_()
+{
+}
+
+
+bool
+Reader::parse( const std::string &document,
+ Value &root,
+ bool collectComments )
+{
+ document_ = document;
+ const char *begin = document_.c_str();
+ const char *end = begin + document_.length();
+ return parse( begin, end, root, collectComments );
+}
+
+
+bool
+Reader::parse( std::istream& sin,
+ Value &root,
+ bool collectComments )
+{
+ //std::istream_iterator<char> begin(sin);
+ //std::istream_iterator<char> end;
+ // Those would allow streamed input from a file, if parse() were a
+ // template function.
+
+ // Since std::string is reference-counted, this at least does not
+ // create an extra copy.
+ std::string doc;
+ std::getline(sin, doc, (char)EOF);
+ return parse( doc, root, collectComments );
+}
+
+bool
+Reader::parse( const char *beginDoc, const char *endDoc,
+ Value &root,
+ bool collectComments )
+{
+ if ( !features_.allowComments_ )
+ {
+ collectComments = false;
+ }
+
+ begin_ = beginDoc;
+ end_ = endDoc;
+ collectComments_ = collectComments;
+ current_ = begin_;
+ lastValueEnd_ = 0;
+ lastValue_ = 0;
+ commentsBefore_ = "";
+ errors_.clear();
+ while ( !nodes_.empty() )
+ nodes_.pop();
+ nodes_.push( &root );
+
+ bool successful = readValue();
+ Token token;
+ skipCommentTokens( token );
+ if ( collectComments_ && !commentsBefore_.empty() )
+ root.setComment( commentsBefore_, commentAfter );
+ if ( features_.strictRoot_ )
+ {
+ if ( !root.isArray() && !root.isObject() )
+ {
+ // Set error location to start of doc, ideally should be first token found in doc
+ token.type_ = tokenError;
+ token.start_ = beginDoc;
+ token.end_ = endDoc;
+ addError( "A valid JSON document must be either an array or an object value.",
+ token );
+ return false;
+ }
+ }
+ return successful;
+}
+
+
+bool
+Reader::readValue()
+{
+ Token token;
+ skipCommentTokens( token );
+ bool successful = true;
+
+ if ( collectComments_ && !commentsBefore_.empty() )
+ {
+ currentValue().setComment( commentsBefore_, commentBefore );
+ commentsBefore_ = "";
+ }
+
+
+ switch ( token.type_ )
+ {
+ case tokenObjectBegin:
+ successful = readObject( token );
+ break;
+ case tokenArrayBegin:
+ successful = readArray( token );
+ break;
+ case tokenNumber:
+ successful = decodeNumber( token );
+ break;
+ case tokenString:
+ successful = decodeString( token );
+ break;
+ case tokenTrue:
+ currentValue() = true;
+ break;
+ case tokenFalse:
+ currentValue() = false;
+ break;
+ case tokenNull:
+ currentValue() = Value();
+ break;
+ default:
+ return addError( "Syntax error: value, object or array expected.", token );
+ }
+
+ if ( collectComments_ )
+ {
+ lastValueEnd_ = current_;
+ lastValue_ = &currentValue();
+ }
+
+ return successful;
+}
+
+
+void
+Reader::skipCommentTokens( Token &token )
+{
+ if ( features_.allowComments_ )
+ {
+ do
+ {
+ readToken( token );
+ }
+ while ( token.type_ == tokenComment );
+ }
+ else
+ {
+ readToken( token );
+ }
+}
+
+
+bool
+Reader::expectToken( TokenType type, Token &token, const char *message )
+{
+ readToken( token );
+ if ( token.type_ != type )
+ return addError( message, token );
+ return true;
+}
+
+
+bool
+Reader::readToken( Token &token )
+{
+ skipSpaces();
+ token.start_ = current_;
+ Char c = getNextChar();
+ bool ok = true;
+ switch ( c )
+ {
+ case '{':
+ token.type_ = tokenObjectBegin;
+ break;
+ case '}':
+ token.type_ = tokenObjectEnd;
+ break;
+ case '[':
+ token.type_ = tokenArrayBegin;
+ break;
+ case ']':
+ token.type_ = tokenArrayEnd;
+ break;
+ case '"':
+ token.type_ = tokenString;
+ ok = readString();
+ break;
+ case '/':
+ token.type_ = tokenComment;
+ ok = readComment();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ token.type_ = tokenNumber;
+ readNumber();
+ break;
+ case 't':
+ token.type_ = tokenTrue;
+ ok = match( "rue", 3 );
+ break;
+ case 'f':
+ token.type_ = tokenFalse;
+ ok = match( "alse", 4 );
+ break;
+ case 'n':
+ token.type_ = tokenNull;
+ ok = match( "ull", 3 );
+ break;
+ case ',':
+ token.type_ = tokenArraySeparator;
+ break;
+ case ':':
+ token.type_ = tokenMemberSeparator;
+ break;
+ case 0:
+ token.type_ = tokenEndOfStream;
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ if ( !ok )
+ token.type_ = tokenError;
+ token.end_ = current_;
+ return true;
+}
+
+
+void
+Reader::skipSpaces()
+{
+ while ( current_ != end_ )
+ {
+ Char c = *current_;
+ if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' )
+ ++current_;
+ else
+ break;
+ }
+}
+
+
+bool
+Reader::match( Location pattern,
+ int patternLength )
+{
+ if ( end_ - current_ < patternLength )
+ return false;
+ int index = patternLength;
+ while ( index-- )
+ if ( current_[index] != pattern[index] )
+ return false;
+ current_ += patternLength;
+ return true;
+}
+
+
+bool
+Reader::readComment()
+{
+ Location commentBegin = current_ - 1;
+ Char c = getNextChar();
+ bool successful = false;
+ if ( c == '*' )
+ successful = readCStyleComment();
+ else if ( c == '/' )
+ successful = readCppStyleComment();
+ if ( !successful )
+ return false;
+
+ if ( collectComments_ )
+ {
+ CommentPlacement placement = commentBefore;
+ if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) )
+ {
+ if ( c != '*' || !containsNewLine( commentBegin, current_ ) )
+ placement = commentAfterOnSameLine;
+ }
+
+ addComment( commentBegin, current_, placement );
+ }
+ return true;
+}
+
+
+void
+Reader::addComment( Location begin,
+ Location end,
+ CommentPlacement placement )
+{
+ assert( collectComments_ );
+ if ( placement == commentAfterOnSameLine )
+ {
+ assert( lastValue_ != 0 );
+ lastValue_->setComment( std::string( begin, end ), placement );
+ }
+ else
+ {
+ if ( !commentsBefore_.empty() )
+ commentsBefore_ += "\n";
+ commentsBefore_ += std::string( begin, end );
+ }
+}
+
+
+bool
+Reader::readCStyleComment()
+{
+ while ( current_ != end_ )
+ {
+ Char c = getNextChar();
+ if ( c == '*' && *current_ == '/' )
+ break;
+ }
+ return getNextChar() == '/';
+}
+
+
+bool
+Reader::readCppStyleComment()
+{
+ while ( current_ != end_ )
+ {
+ Char c = getNextChar();
+ if ( c == '\r' || c == '\n' )
+ break;
+ }
+ return true;
+}
+
+
+void
+Reader::readNumber()
+{
+ while ( current_ != end_ )
+ {
+ if ( !(*current_ >= '0' && *current_ <= '9') &&
+ !in( *current_, '.', 'e', 'E', '+', '-' ) )
+ break;
+ ++current_;
+ }
+}
+
+bool
+Reader::readString()
+{
+ Char c = 0;
+ while ( current_ != end_ )
+ {
+ c = getNextChar();
+ if ( c == '\\' )
+ getNextChar();
+ else if ( c == '"' )
+ break;
+ }
+ return c == '"';
+}
+
+
+bool
+Reader::readObject( Token &/*tokenStart*/ )
+{
+ Token tokenName;
+ std::string name;
+ currentValue() = Value( objectValue );
+ while ( readToken( tokenName ) )
+ {
+ bool initialTokenOk = true;
+ while ( tokenName.type_ == tokenComment && initialTokenOk )
+ initialTokenOk = readToken( tokenName );
+ if ( !initialTokenOk )
+ break;
+ if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object
+ return true;
+ if ( tokenName.type_ != tokenString )
+ break;
+
+ name = "";
+ if ( !decodeString( tokenName, name ) )
+ return recoverFromError( tokenObjectEnd );
+
+ Token colon;
+ if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
+ {
+ return addErrorAndRecover( "Missing ':' after object member name",
+ colon,
+ tokenObjectEnd );
+ }
+ Value &value = currentValue()[ name ];
+ nodes_.push( &value );
+ bool ok = readValue();
+ nodes_.pop();
+ if ( !ok ) // error already set
+ return recoverFromError( tokenObjectEnd );
+
+ Token comma;
+ if ( !readToken( comma )
+ || ( comma.type_ != tokenObjectEnd &&
+ comma.type_ != tokenArraySeparator &&
+ comma.type_ != tokenComment ) )
+ {
+ return addErrorAndRecover( "Missing ',' or '}' in object declaration",
+ comma,
+ tokenObjectEnd );
+ }
+ bool finalizeTokenOk = true;
+ while ( comma.type_ == tokenComment &&
+ finalizeTokenOk )
+ finalizeTokenOk = readToken( comma );
+ if ( comma.type_ == tokenObjectEnd )
+ return true;
+ }
+ return addErrorAndRecover( "Missing '}' or object member name",
+ tokenName,
+ tokenObjectEnd );
+}
+
+
+bool
+Reader::readArray( Token &/*tokenStart*/ )
+{
+ currentValue() = Value( arrayValue );
+ skipSpaces();
+ if ( *current_ == ']' ) // empty array
+ {
+ Token endArray;
+ readToken( endArray );
+ return true;
+ }
+ int index = 0;
+ for (;;)
+ {
+ Value &value = currentValue()[ index++ ];
+ nodes_.push( &value );
+ bool ok = readValue();
+ nodes_.pop();
+ if ( !ok ) // error already set
+ return recoverFromError( tokenArrayEnd );
+
+ Token token;
+ // Accept Comment after last item in the array.
+ ok = readToken( token );
+ while ( token.type_ == tokenComment && ok )
+ {
+ ok = readToken( token );
+ }
+ bool badTokenType = ( token.type_ != tokenArraySeparator &&
+ token.type_ != tokenArrayEnd );
+ if ( !ok || badTokenType )
+ {
+ return addErrorAndRecover( "Missing ',' or ']' in array declaration",
+ token,
+ tokenArrayEnd );
+ }
+ if ( token.type_ == tokenArrayEnd )
+ break;
+ }
+ return true;
+}
+
+
+bool
+Reader::decodeNumber( Token &token )
+{
+ bool isDouble = false;
+ for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
+ {
+ isDouble = isDouble
+ || in( *inspect, '.', 'e', 'E', '+' )
+ || ( *inspect == '-' && inspect != token.start_ );
+ }
+ if ( isDouble )
+ return decodeDouble( token );
+ // Attempts to parse the number as an integer. If the number is
+ // larger than the maximum supported value of an integer then
+ // we decode the number as a double.
+ Location current = token.start_;
+ bool isNegative = *current == '-';
+ if ( isNegative )
+ ++current;
+ Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
+ : Value::maxLargestUInt;
+ Value::LargestUInt threshold = maxIntegerValue / 10;
+ Value::LargestUInt value = 0;
+ while ( current < token.end_ )
+ {
+ Char c = *current++;
+ if ( c < '0' || c > '9' )
+ return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
+ Value::UInt digit(c - '0');
+ if ( value >= threshold )
+ {
+ // We've hit or exceeded the max value divided by 10 (rounded down). If
+ // a) we've only just touched the limit, b) this is the last digit, and
+ // c) it's small enough to fit in that rounding delta, we're okay.
+ // Otherwise treat this number as a double to avoid overflow.
+ if (value > threshold ||
+ current != token.end_ ||
+ digit > maxIntegerValue % 10)
+ {
+ return decodeDouble( token );
+ }
+ }
+ value = value * 10 + digit;
+ }
+ if ( isNegative )
+ currentValue() = -Value::LargestInt( value );
+ else if ( value <= Value::LargestUInt(Value::maxInt) )
+ currentValue() = Value::LargestInt( value );
+ else
+ currentValue() = value;
+ return true;
+}
+
+
+bool
+Reader::decodeDouble( Token &token )
+{
+ double value = 0;
+ const int bufferSize = 32;
+ int count;
+ int length = int(token.end_ - token.start_);
+
+ // Sanity check to avoid buffer overflow exploits.
+ if (length < 0) {
+ return addError( "Unable to parse token length", token );
+ }
+
+ // Avoid using a string constant for the format control string given to
+ // sscanf, as this can cause hard to debug crashes on OS X. See here for more
+ // info:
+ //
+ // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
+ char format[] = "%lf";
+
+ if ( length <= bufferSize )
+ {
+ Char buffer[bufferSize+1];
+ memcpy( buffer, token.start_, length );
+ buffer[length] = 0;
+ count = sscanf( buffer, format, &value );
+ }
+ else
+ {
+ std::string buffer( token.start_, token.end_ );
+ count = sscanf( buffer.c_str(), format, &value );
+ }
+
+ if ( count != 1 )
+ return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
+ currentValue() = value;
+ return true;
+}
+
+
+bool
+Reader::decodeString( Token &token )
+{
+ std::string decoded;
+ if ( !decodeString( token, decoded ) )
+ return false;
+ currentValue() = decoded;
+ return true;
+}
+
+
+bool
+Reader::decodeString( Token &token, std::string &decoded )
+{
+ decoded.reserve( token.end_ - token.start_ - 2 );
+ Location current = token.start_ + 1; // skip '"'
+ Location end = token.end_ - 1; // do not include '"'
+ while ( current != end )
+ {
+ Char c = *current++;
+ if ( c == '"' )
+ break;
+ else if ( c == '\\' )
+ {
+ if ( current == end )
+ return addError( "Empty escape sequence in string", token, current );
+ Char escape = *current++;
+ switch ( escape )
+ {
+ case '"': decoded += '"'; break;
+ case '/': decoded += '/'; break;
+ case '\\': decoded += '\\'; break;
+ case 'b': decoded += '\b'; break;
+ case 'f': decoded += '\f'; break;
+ case 'n': decoded += '\n'; break;
+ case 'r': decoded += '\r'; break;
+ case 't': decoded += '\t'; break;
+ case 'u':
+ {
+ unsigned int unicode;
+ if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
+ return false;
+ decoded += codePointToUTF8(unicode);
+ }
+ break;
+ default:
+ return addError( "Bad escape sequence in string", token, current );
+ }
+ }
+ else
+ {
+ decoded += c;
+ }
+ }
+ return true;
+}
+
+bool
+Reader::decodeUnicodeCodePoint( Token &token,
+ Location &current,
+ Location end,
+ unsigned int &unicode )
+{
+
+ if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
+ return false;
+ if (unicode >= 0xD800 && unicode <= 0xDBFF)
+ {
+ // surrogate pairs
+ if (end - current < 6)
+ return addError( "additional six characters expected to parse unicode surrogate pair.", token, current );
+ unsigned int surrogatePair;
+ if (*(current++) == '\\' && *(current++)== 'u')
+ {
+ if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
+ {
+ unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
+ }
+ else
+ return false;
+ }
+ else
+ return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
+ }
+ return true;
+}
+
+bool
+Reader::decodeUnicodeEscapeSequence( Token &token,
+ Location &current,
+ Location end,
+ unsigned int &unicode )
+{
+ if ( end - current < 4 )
+ return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
+ unicode = 0;
+ for ( int index =0; index < 4; ++index )
+ {
+ Char c = *current++;
+ unicode *= 16;
+ if ( c >= '0' && c <= '9' )
+ unicode += c - '0';
+ else if ( c >= 'a' && c <= 'f' )
+ unicode += c - 'a' + 10;
+ else if ( c >= 'A' && c <= 'F' )
+ unicode += c - 'A' + 10;
+ else
+ return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
+ }
+ return true;
+}
+
+
+bool
+Reader::addError( const std::string &message,
+ Token &token,
+ Location extra )
+{
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = extra;
+ errors_.push_back( info );
+ return false;
+}
+
+
+bool
+Reader::recoverFromError( TokenType skipUntilToken )
+{
+ int errorCount = int(errors_.size());
+ Token skip;
+ for (;;)
+ {
+ if ( !readToken(skip) )
+ errors_.resize( errorCount ); // discard errors caused by recovery
+ if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
+ break;
+ }
+ errors_.resize( errorCount );
+ return false;
+}
+
+
+bool
+Reader::addErrorAndRecover( const std::string &message,
+ Token &token,
+ TokenType skipUntilToken )
+{
+ addError( message, token );
+ return recoverFromError( skipUntilToken );
+}
+
+
+Value &
+Reader::currentValue()
+{
+ return *(nodes_.top());
+}
+
+
+Reader::Char
+Reader::getNextChar()
+{
+ if ( current_ == end_ )
+ return 0;
+ return *current_++;
+}
+
+
+void
+Reader::getLocationLineAndColumn( Location location,
+ int &line,
+ int &column ) const
+{
+ Location current = begin_;
+ Location lastLineStart = current;
+ line = 0;
+ while ( current < location && current != end_ )
+ {
+ Char c = *current++;
+ if ( c == '\r' )
+ {
+ if ( *current == '\n' )
+ ++current;
+ lastLineStart = current;
+ ++line;
+ }
+ else if ( c == '\n' )
+ {
+ lastLineStart = current;
+ ++line;
+ }
+ }
+ // column & line start at 1
+ column = int(location - lastLineStart) + 1;
+ ++line;
+}
+
+
+std::string
+Reader::getLocationLineAndColumn( Location location ) const
+{
+ int line, column;
+ getLocationLineAndColumn( location, line, column );
+ char buffer[18+16+16+1];
+ sprintf( buffer, "Line %d, Column %d", line, column );
+ return buffer;
+}
+
+
+// Deprecated. Preserved for backward compatibility
+std::string
+Reader::getFormatedErrorMessages() const
+{
+ return getFormattedErrorMessages();
+}
+
+
+std::string
+Reader::getFormattedErrorMessages() const
+{
+ std::string formattedMessage;
+ for ( Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError )
+ {
+ const ErrorInfo &error = *itError;
+ formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
+ formattedMessage += " " + error.message_ + "\n";
+ if ( error.extra_ )
+ formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
+ }
+ return formattedMessage;
+}
+
+
+std::istream& operator>>( std::istream &sin, Value &root )
+{
+ Json::Reader reader;
+ bool ok = reader.parse(sin, root, true);
+ if (!ok) {
+ fprintf(
+ stderr,
+ "Error from reader: %s",
+ reader.getFormattedErrorMessages().c_str());
+
+ JSON_FAIL_MESSAGE("reader error");
+ }
+ return sin;
+}
+
+
+} // namespace Json
diff --git a/chromium/third_party/jsoncpp/overrides/src/lib_json/json_value.cpp b/chromium/third_party/jsoncpp/overrides/src/lib_json/json_value.cpp
index 850724fd3e3..a2a4a6761d2 100644
--- a/chromium/third_party/jsoncpp/overrides/src/lib_json/json_value.cpp
+++ b/chromium/third_party/jsoncpp/overrides/src/lib_json/json_value.cpp
@@ -27,8 +27,14 @@
namespace Json {
// This is a walkaround to avoid the static initialization of Value::null.
-// const Value Value::null;
-static const unsigned char kNull[sizeof(Value)] = { 0 };
+// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
+// 8 (instead of 4) as a bit of future-proofing.
+#if defined(__ARMEL__)
+#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
+#else
+#define ALIGNAS(byte_alignment)
+#endif
+static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = {0};
const Value& Value::null = reinterpret_cast<const Value&>(kNull);
const Int Value::minInt = Int( ~(UInt(-1)/2) );