Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: components/safe_json/json_sanitizer_android.cc

Issue 1203083002: Add a JSON sanitizer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: build files Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/safe_json/json_sanitizer.cc ('k') | components/safe_json/json_sanitizer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/safe_json/json_sanitizer.h"
6
7 #include "base/android/jni_string.h"
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_util.h"
13 #include "jni/JsonSanitizer_jni.h"
14
15 namespace safe_json {
16
17 namespace {
18
19 // An implementation of JsonSanitizer that calls into Java. It deals with
20 // malformed input (in particular malformed Unicode encodings) in the following
21 // steps:
22 // 1. The input string is checked for whether it is well-formed UTF-8. Malformed
23 // UTF-8 is rejected.
24 // 2. The UTF-8 string is converted in native code to a Java String, which is
25 // encoded as UTF-16.
26 // 2. The Java String is parsed as JSON in the memory-safe environment of the
27 // Java VM and any string literals are unescaped.
28 // 3. The string literals themselves are now untrusted, so they are checked in
29 // Java for whether they are valid UTF-16.
30 // 4. The parsed JSON with sanitized literals is encoded back into a Java
31 // String and passed back to native code.
32 // 5. The Java String is converted back to UTF-8 in native code.
33 // This ensures that both invalid UTF-8 and invalid escaped UTF-16 will be
34 // rejected.
35 class JsonSanitizerAndroid : public JsonSanitizer {
36 public:
37 JsonSanitizerAndroid(const StringCallback& success_callback,
38 const StringCallback& error_callback);
39 ~JsonSanitizerAndroid() {}
40
41 void Sanitize(const std::string& unsafe_json);
42
43 void OnSuccess(const std::string& json);
44 void OnError(const std::string& error);
45
46 private:
47 StringCallback success_callback_;
48 StringCallback error_callback_;
49
50 DISALLOW_COPY_AND_ASSIGN(JsonSanitizerAndroid);
51 };
52
53 JsonSanitizerAndroid::JsonSanitizerAndroid(
54 const StringCallback& success_callback,
55 const StringCallback& error_callback)
56 : success_callback_(success_callback),
57 error_callback_(error_callback) {}
58
59 void JsonSanitizerAndroid::Sanitize(const std::string& unsafe_json) {
60 // The JSON parser only accepts wellformed UTF-8.
61 if (!base::IsStringUTF8(unsafe_json)) {
62 OnError("Unsupported encoding");
63 return;
64 }
65
66 JNIEnv* env = base::android::AttachCurrentThread();
67 base::android::ScopedJavaLocalRef<jstring> unsafe_json_java =
68 base::android::ConvertUTF8ToJavaString(env, unsafe_json);
69
70 // This will synchronously call either OnSuccess() or OnError().
71 Java_JsonSanitizer_sanitize(env, reinterpret_cast<jlong>(this),
72 unsafe_json_java.obj());
73 }
74
75 void JsonSanitizerAndroid::OnSuccess(const std::string& json) {
76 base::MessageLoop::current()->PostTask(FROM_HERE,
77 base::Bind(success_callback_, json));
78 }
79
80 void JsonSanitizerAndroid::OnError(const std::string& error) {
81 base::MessageLoop::current()->PostTask(FROM_HERE,
82 base::Bind(error_callback_, error));
83 }
84
85 } // namespace
86
87 void OnSuccess(JNIEnv* env, jclass clazz, jlong jsanitizer, jstring json) {
88 JsonSanitizerAndroid* sanitizer =
89 reinterpret_cast<JsonSanitizerAndroid*>(jsanitizer);
90 sanitizer->OnSuccess(base::android::ConvertJavaStringToUTF8(env, json));
91 }
92
93 void OnError(JNIEnv* env, jclass clazz, jlong jsanitizer, jstring error) {
94 JsonSanitizerAndroid* sanitizer =
95 reinterpret_cast<JsonSanitizerAndroid*>(jsanitizer);
96 sanitizer->OnError(base::android::ConvertJavaStringToUTF8(env, error));
97 }
98
99 // static
100 void JsonSanitizer::Sanitize(const std::string& unsafe_json,
101 const StringCallback& success_callback,
102 const StringCallback& error_callback) {
103 // JsonSanitizerAndroid does all its work synchronously, but posts any
104 // callbacks to the current message loop. This means it can be destroyed at
105 // the end of this method.
106 JsonSanitizerAndroid sanitizer(success_callback, error_callback);
107 sanitizer.Sanitize(unsafe_json);
108 }
109
110 // static
111 bool JsonSanitizer::Register(JNIEnv* env) {
112 return RegisterNativesImpl(env);
113 }
114
115 } // namespace safe_json
OLDNEW
« no previous file with comments | « components/safe_json/json_sanitizer.cc ('k') | components/safe_json/json_sanitizer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698