summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-10 18:32:47 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-10 18:32:47 +0000
commitde36240ae4c0ccec2d96b17e2390fd89b936e94d (patch)
tree10d06c71f7b38d6ed439ad7a67af604c1263a0e0 /net
parentcbdf6d505803f1467d90f5cfa2624a0d51386422 (diff)
downloadchromium_src-de36240ae4c0ccec2d96b17e2390fd89b936e94d.zip
chromium_src-de36240ae4c0ccec2d96b17e2390fd89b936e94d.tar.gz
chromium_src-de36240ae4c0ccec2d96b17e2390fd89b936e94d.tar.bz2
Implement alternative string conversion functions in net/ on Android,
using Java conversion functions. This is part of making it possible to build net/ without ICU, to get binary size down when building net/ as a library BUG=362608 Review URL: https://codereview.chromium.org/266053002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269595 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/DEPS4
-rw-r--r--net/android/java/src/org/chromium/net/NetStringUtil.java89
-rw-r--r--net/android/net_jni_registrar.cc7
-rw-r--r--net/base/net_string_util.h15
-rw-r--r--net/base/net_string_util_icu.cc16
-rw-r--r--net/base/net_string_util_icu_alternatives_android.cc115
-rw-r--r--net/base/net_string_util_icu_alternatives_android.h18
-rw-r--r--net/cert/x509_cert_types_mac.cc2
-rw-r--r--net/http/http_auth_handler_basic.cc4
-rw-r--r--net/http/http_auth_handler_digest.cc2
-rw-r--r--net/net.gyp18
-rw-r--r--net/proxy/proxy_script_fetcher_impl.cc13
12 files changed, 272 insertions, 31 deletions
diff --git a/net/DEPS b/net/DEPS
index e30167c..f5b5331 100644
--- a/net/DEPS
+++ b/net/DEPS
@@ -44,10 +44,6 @@ specific_include_rules = {
"+third_party/icu/source/common/unicode/ucnv.h"
],
- # Only use icu for string conversions.
- "proxy_script_fetcher_impl\.cc": [
- "+base/i18n/icu_string_conversions.h",
- ],
"websocket_channel\.h": [
"+base/i18n",
],
diff --git a/net/android/java/src/org/chromium/net/NetStringUtil.java b/net/android/java/src/org/chromium/net/NetStringUtil.java
new file mode 100644
index 0000000..4ab1bd9
--- /dev/null
+++ b/net/android/java/src/org/chromium/net/NetStringUtil.java
@@ -0,0 +1,89 @@
+// Copyright 2014 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.
+
+package org.chromium.net;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
+import java.text.Normalizer;
+
+/**
+ * Utility functions for converting strings between formats when not built with
+ * icu.
+ */
+@JNINamespace("net::android")
+public class NetStringUtil {
+ /**
+ * Attempts to convert text in a given character set to a Unicode string.
+ * Returns null on failure.
+ * @param text ByteBuffer containing the character array to convert.
+ * @param charset Character set it's in encoded in.
+ * @return: Unicode string on success, null on failure.
+ */
+ @CalledByNative
+ private static String convertToUnicode(
+ ByteBuffer text,
+ String charset_name) {
+ try {
+ Charset charset = Charset.forName(charset_name);
+ CharsetDecoder decoder = charset.newDecoder();
+ // On invalid characters, this will throw an exception.
+ return decoder.decode(text).toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Attempts to convert text in a given character set to a Unicode string,
+ * and normalize it. Returns null on failure.
+ * @param text ByteBuffer containing the character array to convert.
+ * @param charset Character set it's in encoded in.
+ * @return: Unicode string on success, null on failure.
+ */
+ @CalledByNative
+ private static String convertToUnicodeAndNormalize(
+ ByteBuffer text,
+ String charset_name) {
+ String unicodeString = convertToUnicode(text, charset_name);
+ if (unicodeString == null)
+ return unicodeString;
+ return Normalizer.normalize(unicodeString, Normalizer.Form.NFC);
+ }
+
+ /**
+ * Convert text in a given character set to a Unicode string. Any invalid
+ * characters are replaced with U+FFFD. Returns null if the character set
+ * is not recognized.
+ * @param text ByteBuffer containing the character array to convert.
+ * @param charset Character set it's in encoded in.
+ * @return: Unicode string on success, null on failure.
+ */
+ @CalledByNative
+ private static String convertToUnicodeWithSubstitutions(
+ ByteBuffer text,
+ String charset_name) {
+ try {
+ Charset charset = Charset.forName(charset_name);
+
+ // TODO(mmenke): Investigate if Charset.decode() can be used
+ // instead. The question is whether it uses the proper replace
+ // character. JDK CharsetDecoder docs say U+FFFD is the default,
+ // but Charset.decode() docs say it uses the "charset's default
+ // replacement byte array".
+ CharsetDecoder decoder = charset.newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ decoder.replaceWith("\uFFFD");
+ return decoder.decode(text).toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/net/android/net_jni_registrar.cc b/net/android/net_jni_registrar.cc
index b3e9437..ebc7276 100644
--- a/net/android/net_jni_registrar.cc
+++ b/net/android/net_jni_registrar.cc
@@ -15,6 +15,10 @@
#include "net/cert/x509_util_android.h"
#include "net/proxy/proxy_config_service_android.h"
+#if defined(USE_ICU_ALTERNATIVES)
+#include "net/base/net_string_util_icu_alternatives_android.h"
+#endif
+
namespace net {
namespace android {
@@ -28,6 +32,9 @@ static base::android::RegistrationMethod kNetRegisteredMethods[] = {
net::NetworkChangeNotifierAndroid::Register },
{ "ProxyConfigService", net::ProxyConfigServiceAndroid::Register },
{ "X509Util", net::RegisterX509Util },
+#if defined(USE_ICU_ALTERNATIVES)
+ { "NetStringUtils", net::RegisterNetStringUtils }
+#endif
};
bool RegisterJni(JNIEnv* env) {
diff --git a/net/base/net_string_util.h b/net/base/net_string_util.h
index ce5fdf5..8e959a0 100644
--- a/net/base/net_string_util.h
+++ b/net/base/net_string_util.h
@@ -14,6 +14,8 @@
namespace net {
+extern const char* const kCharsetLatin1;
+
// Converts |text| using |charset| to UTF-8, and writes it to |output|.
// On failure, returns false and |output| is cleared.
bool ConvertToUtf8(const std::string& text, const char* charset,
@@ -24,19 +26,16 @@ bool ConvertToUtf8(const std::string& text, const char* charset,
bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset,
std::string* output);
-// Converts |text| encoded in Latin-1 to UTF-8, normalizes the result, and
-// writes it to |output|. On failure, returns false and |output| is cleared.
-bool ConvertLatin1ToUtf8AndNormalize(const std::string& text,
- std::string* output);
-
// Converts |text| using |charset| to UTF-16, and writes it to |output|.
// On failure, returns false and |output| is cleared.
bool ConvertToUTF16(const std::string& text, const char* charset,
base::string16* output);
-// Converts |text| encoded in Latin-1 to UTF-16, and writes it to |output|.
-// On failure, returns false and |output| is cleared.
-bool ConvertLatin1ToUTF16(const std::string& text, base::string16* output);
+// Converts |text| using |charset| to UTF-16, and writes it to |output|.
+// Any characters that can not be converted are replaced with U+FFFD.
+bool ConvertToUTF16WithSubstitutions(const std::string& text,
+ const char* charset,
+ base::string16* output);
} // namespace net
diff --git a/net/base/net_string_util_icu.cc b/net/base/net_string_util_icu.cc
index f8a1ce7..435f9de 100644
--- a/net/base/net_string_util_icu.cc
+++ b/net/base/net_string_util_icu.cc
@@ -11,6 +11,8 @@
namespace net {
+const char* const kCharsetLatin1 = base::kCodepageLatin1;
+
bool ConvertToUtf8(const std::string& text, const char* charset,
std::string* output) {
output->clear();
@@ -43,20 +45,18 @@ bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset,
return base::ConvertToUtf8AndNormalize(text, charset, output);
}
-bool ConvertLatin1ToUtf8AndNormalize(const std::string& text,
- std::string* output) {
- return net::ConvertToUtf8AndNormalize(text, base::kCodepageLatin1, output);
-}
-
bool ConvertToUTF16(const std::string& text, const char* charset,
base::string16* output) {
return base::CodepageToUTF16(text, charset,
base::OnStringConversionError::FAIL, output);
}
-bool ConvertLatin1ToUTF16(const std::string& text, base::string16* output) {
- return base::CodepageToUTF16(text, base::kCodepageLatin1,
- base::OnStringConversionError::FAIL, output);
+bool ConvertToUTF16WithSubstitutions(const std::string& text,
+ const char* charset,
+ base::string16* output) {
+ return base::CodepageToUTF16(text, charset,
+ base::OnStringConversionError::SUBSTITUTE,
+ output);
}
} // namespace net
diff --git a/net/base/net_string_util_icu_alternatives_android.cc b/net/base/net_string_util_icu_alternatives_android.cc
new file mode 100644
index 0000000..ca06303
--- /dev/null
+++ b/net/base/net_string_util_icu_alternatives_android.cc
@@ -0,0 +1,115 @@
+// Copyright 2014 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 "net/base/net_string_util_icu_alternatives_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "jni/NetStringUtil_jni.h"
+#include "net/base/net_string_util.h"
+
+namespace net {
+
+namespace {
+
+// Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
+// string). Returns the result jstring, or NULL on failure.
+ScopedJavaLocalRef<jstring> ConvertToJstring(const std::string& text,
+ const char* charset) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ jobject java_byte_buffer =
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ base::android::ScopedJavaLocalRef<jstring> java_charset =
+ base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+ ScopedJavaLocalRef<jstring> java_result =
+ android::Java_NetStringUtil_convertToUnicode(env, java_byte_buffer,
+ java_charset.obj());
+ return java_result;
+}
+
+// Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
+// string) and then normalizes the string. Returns the result jstring, or NULL
+// on failure.
+ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(
+ const std::string& text, const char* charset) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ jobject java_byte_buffer =
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ base::android::ScopedJavaLocalRef<jstring> java_charset =
+ base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+ ScopedJavaLocalRef<jstring> java_result =
+ android::Java_NetStringUtil_convertToUnicodeAndNormalize(
+ env, java_byte_buffer, java_charset.obj());
+ return java_result;
+}
+
+// Converts |text| encoded in |charset| to a jstring (Java unicode string).
+// Any characters that can not be converted are replaced with U+FFFD.
+ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions(
+ const std::string& text, const char* charset) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ jobject java_byte_buffer =
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ base::android::ScopedJavaLocalRef<jstring> java_charset =
+ base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+ ScopedJavaLocalRef<jstring> java_result =
+ android::Java_NetStringUtil_convertToUnicodeWithSubstitutions(
+ env, java_byte_buffer, java_charset.obj());
+ return java_result;
+}
+
+} // namespace
+
+const char* const kCharsetLatin1 = "ISO-8859-1";
+
+bool ConvertToUtf8(const std::string& text, const char* charset,
+ std::string* output) {
+ output->clear();
+ ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset);
+ if (java_result.is_null())
+ return false;
+ *output = base::android::ConvertJavaStringToUTF8(java_result);
+ return true;
+}
+
+bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset,
+ std::string* output) {
+ output->clear();
+ ScopedJavaLocalRef<jstring> java_result = ConvertToNormalizedJstring(
+ text, charset);
+ if (java_result.is_null())
+ return false;
+ *output = base::android::ConvertJavaStringToUTF8(java_result);
+ return true;
+}
+
+bool ConvertToUTF16(const std::string& text, const char* charset,
+ base::string16* output) {
+ output->clear();
+ ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset);
+ if (java_result.is_null())
+ return false;
+ *output = base::android::ConvertJavaStringToUTF16(java_result);
+ return true;
+}
+
+bool ConvertToUTF16WithSubstitutions(const std::string& text,
+ const char* charset,
+ base::string16* output) {
+ output->clear();
+ ScopedJavaLocalRef<jstring> java_result =
+ ConvertToJstringWithSubstitutions(text, charset);
+ if (java_result.is_null())
+ return false;
+ *output = base::android::ConvertJavaStringToUTF16(java_result);
+ return true;
+}
+
+bool RegisterNetStringUtils(JNIEnv* env) {
+ return android::RegisterNativesImpl(env);
+}
+
+} // namespace net
diff --git a/net/base/net_string_util_icu_alternatives_android.h b/net/base/net_string_util_icu_alternatives_android.h
new file mode 100644
index 0000000..c3a6cf5
--- /dev/null
+++ b/net/base/net_string_util_icu_alternatives_android.h
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_
+#define NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_
+
+#include <jni.h>
+
+namespace net {
+
+// Explicitly register static JNI functions needed when not using ICU.
+bool RegisterNetStringUtils(JNIEnv* env);
+
+} // namespace net
+
+#endif // NET_BASE_NET_STRING_UTIL_ICU_ALTERNATIVES_ANDROID_H_
+
diff --git a/net/cert/x509_cert_types_mac.cc b/net/cert/x509_cert_types_mac.cc
index 244fe99..d5b2ea3 100644
--- a/net/cert/x509_cert_types_mac.cc
+++ b/net/cert/x509_cert_types_mac.cc
@@ -115,7 +115,7 @@ std::string DataToString(CSSM_DATA data) {
// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8.
std::string Latin1DataToUTF8String(CSSM_DATA data) {
base::string16 utf16;
- if (!ConvertLatin1ToUTF16(DataToString(data), &utf16))
+ if (!ConvertToUTF16(DataToString(data), kCharsetLatin1, &utf16))
return "";
return base::UTF16ToUTF8(utf16);
}
diff --git a/net/http/http_auth_handler_basic.cc b/net/http/http_auth_handler_basic.cc
index eace1df..4837138 100644
--- a/net/http/http_auth_handler_basic.cc
+++ b/net/http/http_auth_handler_basic.cc
@@ -43,8 +43,10 @@ bool ParseRealm(const HttpAuthChallengeTokenizer& tokenizer,
if (!LowerCaseEqualsASCII(parameters.name(), "realm"))
continue;
- if (!net::ConvertLatin1ToUtf8AndNormalize(parameters.value(), realm))
+ if (!net::ConvertToUtf8AndNormalize(parameters.value(), kCharsetLatin1,
+ realm)) {
return false;
+ }
}
return parameters.valid();
}
diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc
index ce4b148..7dee081 100644
--- a/net/http/http_auth_handler_digest.cc
+++ b/net/http/http_auth_handler_digest.cc
@@ -227,7 +227,7 @@ bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
const std::string& value) {
if (LowerCaseEqualsASCII(name, "realm")) {
std::string realm;
- if (!net::ConvertLatin1ToUtf8AndNormalize(value, &realm))
+ if (!net::ConvertToUtf8AndNormalize(value, kCharsetLatin1, &realm))
return false;
realm_ = realm;
original_realm_ = value;
diff --git a/net/net.gyp b/net/net.gyp
index 559a7dc..a454e7d 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -438,6 +438,16 @@
],
},
],
+ [ 'use_icu_alternatives_on_android == 1', {
+ 'sources!': [
+ 'base/net_string_util_icu.cc',
+ ],
+ 'sources': [
+ 'base/net_string_util_icu_alternatives_android.cc',
+ 'base/net_string_util_icu_alternatives_android.h',
+ ],
+ },
+ ],
],
'target_conditions': [
# These source files are excluded by default platform rules, but they
@@ -1430,6 +1440,14 @@
'jni_generator_ptr_type': 'long',
},
'includes': [ '../build/jni_generator.gypi' ],
+
+ 'conditions': [
+ ['use_icu_alternatives_on_android==1', {
+ 'sources': [
+ 'android/java/src/org/chromium/net/NetStringUtil.java',
+ ],
+ }],
+ ],
},
{
'target_name': 'net_test_jni_headers',
diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc
index 0887d8c..737c6f8 100644
--- a/net/proxy/proxy_script_fetcher_impl.cc
+++ b/net/proxy/proxy_script_fetcher_impl.cc
@@ -5,7 +5,6 @@
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "base/compiler_specific.h"
-#include "base/i18n/icu_string_conversions.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
@@ -13,6 +12,7 @@
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
+#include "net/base/net_string_util.h"
#include "net/base/request_priority.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
@@ -56,18 +56,15 @@ void ConvertResponseToUTF16(const std::string& charset,
if (charset.empty()) {
// Assume ISO-8859-1 if no charset was specified.
- codepage = base::kCodepageLatin1;
+ codepage = kCharsetLatin1;
} else {
// Otherwise trust the charset that was provided.
codepage = charset.c_str();
}
- // We will be generous in the conversion -- if any characters lie
- // outside of |charset| (i.e. invalid), then substitute them with
- // U+FFFD rather than failing.
- base::CodepageToUTF16(bytes, codepage,
- base::OnStringConversionError::SUBSTITUTE,
- utf16);
+ // Be generous in the conversion -- if any characters lie outside of |charset|
+ // (i.e. invalid), then substitute them with U+FFFD rather than failing.
+ ConvertToUTF16WithSubstitutions(bytes, codepage, utf16);
}
} // namespace