// Copyright 2015 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. #include "components/safe_json/json_sanitizer.h" #if defined(OS_ANDROID) #error Build json_sanitizer_android.cc instead of this file on Android. #endif #include "base/bind.h" #include "base/callback.h" #include "base/json/json_writer.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_util.h" #include "base/values.h" #include "components/safe_json/safe_json_parser.h" namespace safe_json { namespace { class OopJsonSanitizer : public JsonSanitizer { public: OopJsonSanitizer(const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback); private: friend struct base::DefaultDeleter; ~OopJsonSanitizer() {} void OnParseSuccess(scoped_ptr value); void OnParseError(const std::string& error); StringCallback success_callback_; StringCallback error_callback_; DISALLOW_COPY_AND_ASSIGN(OopJsonSanitizer); }; OopJsonSanitizer::OopJsonSanitizer(const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback) : success_callback_(success_callback), error_callback_(error_callback) { SafeJsonParser::Parse(unsafe_json, base::Bind(&OopJsonSanitizer::OnParseSuccess, base::Unretained(this)), base::Bind(&OopJsonSanitizer::OnParseError, base::Unretained(this))); } void OopJsonSanitizer::OnParseSuccess(scoped_ptr value) { // Self-destruct at the end of this method. scoped_ptr deleter(this); // A valid JSON document may only have a dictionary or list as its top-level // type, but the JSON parser also accepts other types, so we filter them out. base::Value::Type type = value->GetType(); if (type != base::Value::TYPE_DICTIONARY && type != base::Value::TYPE_LIST) { error_callback_.Run("Invalid top-level type"); return; } std::string json; if (!base::JSONWriter::Write(*value, &json)) { error_callback_.Run("Encoding error"); return; } success_callback_.Run(json); } void OopJsonSanitizer::OnParseError(const std::string& error) { error_callback_.Run("Parse error: " + error); delete this; } } // namespace // static void JsonSanitizer::Sanitize(const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback) { // OopJsonSanitizer destroys itself when it is finished. new OopJsonSanitizer(unsafe_json, success_callback, error_callback); } } // namespace safe_json