From 1fdc016e583043db89704c2e069581b4b9e5a8af Mon Sep 17 00:00:00 2001 From: jet Date: Tue, 5 Oct 2010 17:24:44 -0600 Subject: [PATCH 01/11] Beginning of branch. Being pushed for testing purposes. --- classpath/java-lang.cpp | 111 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 8303e3e4e1..06bc4e0c2d 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -229,6 +229,82 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid) } return exitCode; } + +void getLocale(char* language, char* region) { + const char* lang = 0; + const char* reg = 0; + + unsigned locale = GetUserDefaultUILanguage(); + unsigned prilang = locale & 0x3ff; + unsigned sublang = locale >> 10; + + switch (prilang) { + case 0x004: { + lang = "zh"; + switch (sublang) { + case 0x01: reg = "Hant"; break; + case 0x02: reg = "Hans"; break; + case 0x03: reg = "HK"; break; + case 0x04: reg = "SG"; break; + } + } break; + case 0x006: lang = "da"; reg = "DK"; break; + case 0x007: lang = "de"; reg = "DE"; break; + case 0x009: { + lang = "en"; + switch (sublang) { + case 0x01: reg = "US"; break; + case 0x02: reg = "GB"; break; + case 0x03: reg = "AU"; break; + case 0x04: reg = "CA"; break; + case 0x05: reg = "NZ"; break; + case 0x06: reg = "IE"; break; + case 0x07: reg = "ZA"; break; + case 0x10: reg = "IN"; break; + } + } break; + case 0x00a: { + lang = "es"; + switch (sublang) { + case 0x01: case: 0x03: reg = "ES"; break; + case 0x02: reg = "MX"; break; + } + } break; + case 0x00c: { + lang = "fr"; + switch (sublang) { + case 0x01: reg = "FR"; break; + case 0x02: reg = "BE"; break; + case 0x03: reg = "CA"; break; + } + } break; + case 0x010: lang = "it"; reg = "IT"; break; + case 0x011: lang = "ja"; reg = "JP"; break; + case 0x012: lang = "ko"; reg = "KR"; break; + case 0x013: { + lang = "nl"; + switch (sublang) { + case 0x01: reg = "NL"; break; + case 0x02: reg = "BE"; break; + } + } break; + case 0x014: lang = "no"; reg = "NO"; break; + case 0x015: lang = "pl"; reg = "PL"; break; + case 0x016: { + lang = "pt"; + switch (sublang) { + case 0x01: reg = "BR"; break; + case 0x02: reg = "PT"; break; + } + } break; + case 0x018: lang = "ro"; reg = "RO"; break; + case 0x019: lang = "ru"; reg = "RU"; break; + case 0x01d: lang = "sv"; reg = "SE"; break; + } + + if (language) memcpy(language, lang, strlen(lang) * sizeof(char)); + if (region) memcpy(region, reg, strlen(reg) * sizeof(char)); +} #else extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, @@ -352,6 +428,32 @@ Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid) return exitCode; } + +void getLocale(char* language, char* region) { + const char* LANG = getenv("LANG"); + + char dummy = '\0'; + char* lang = &dummy; + char* reg = &dummy; + + if (LANG) { + unsigned underscore = 0; + while (underscore < strlen(LANG) && *(LANG + underscore) != '_') ++underscore; + unsigned period = underscore + 1; + while (period < strlen(LANG) && *(LANG + period) != '.') ++period; + + unsigned reglen = period - underscore - 1; + char lang_[underscore + 1]; lang = lang_; + char reg_[reglen + 1]; reg = reg_; + + memcpy(lang, LANG, underscore * sizeof(char)); + memcpy(reg, LANG + underscore + 1, reglen * sizeof(char)); + lang[underscore] = reg[reglen] = '\0'; + } + + if (language) memcpy(language, lang, strlen(lang) * sizeof(char)); + if (region) memcpy(region, reg, strlen(reg) * sizeof(char)); +} #endif extern "C" JNIEXPORT jstring JNICALL @@ -452,6 +554,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, r = e->NewStringUTF(getenv("HOME")); } #endif + else if (strcmp(chars, "user.language") == 0) { + char lang[16]; + getLocale(lang, 0); + if (strlen(lang)) r = e->NewStringUTF(lang); + } else if (strcmp(chars, "user.region") == 0) { + char reg[16]; + getLocale(0, reg); + if (strlen(reg)) r = e->NewStringUTF(reg); + } e->ReleaseStringUTFChars(name, chars); } From 45e6cd5a60165859b17d3f8f0472d95ebc16eb25 Mon Sep 17 00:00:00 2001 From: JET Date: Tue, 5 Oct 2010 17:53:17 -0600 Subject: [PATCH 02/11] The localization properties are now functional. Only 16 languages are currently reported on Windows. --- classpath/java-lang.cpp | 15 ++++++++------- makefile | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 06bc4e0c2d..e0b45b1388 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -231,8 +231,9 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid) } void getLocale(char* language, char* region) { - const char* lang = 0; - const char* reg = 0; + const char dummy = '\0'; + const char* lang = &dummy; + const char* reg = &dummy; unsigned locale = GetUserDefaultUILanguage(); unsigned prilang = locale & 0x3ff; @@ -266,7 +267,7 @@ void getLocale(char* language, char* region) { case 0x00a: { lang = "es"; switch (sublang) { - case 0x01: case: 0x03: reg = "ES"; break; + case 0x01: case 0x03: reg = "ES"; break; case 0x02: reg = "MX"; break; } } break; @@ -302,8 +303,8 @@ void getLocale(char* language, char* region) { case 0x01d: lang = "sv"; reg = "SE"; break; } - if (language) memcpy(language, lang, strlen(lang) * sizeof(char)); - if (region) memcpy(region, reg, strlen(reg) * sizeof(char)); + if (language) memcpy(language, lang, (strlen(lang) + 1) * sizeof(char)); + if (region) memcpy(region, reg, (strlen(reg) + 1) * sizeof(char)); } #else extern "C" JNIEXPORT void JNICALL @@ -451,8 +452,8 @@ void getLocale(char* language, char* region) { lang[underscore] = reg[reglen] = '\0'; } - if (language) memcpy(language, lang, strlen(lang) * sizeof(char)); - if (region) memcpy(region, reg, strlen(reg) * sizeof(char)); + if (language) memcpy(language, lang, (strlen(lang) + 1) * sizeof(char)); + if (region) memcpy(region, reg, (strlen(reg) + 1) * sizeof(char)); } #endif diff --git a/makefile b/makefile index f0dcab31a5..a8b450a7ed 100644 --- a/makefile +++ b/makefile @@ -190,7 +190,7 @@ ifeq ($(platform),windows) exe-suffix = .exe lflags = -L$(lib) $(common-lflags) -lws2_32 -mwindows -mconsole - cflags = -I$(inc) $(common-cflags) + cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 ifeq (,$(filter mingw32 cygwin,$(build-platform))) cxx = i586-mingw32msvc-g++ From 8feb5a8124e4b8a1cef2d7f9e0e84fcf25fa308e Mon Sep 17 00:00:00 2001 From: jet Date: Tue, 5 Oct 2010 22:29:41 -0600 Subject: [PATCH 03/11] Fixed bug where locale region became a copy of the language. --- classpath/java-lang.cpp | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index e0b45b1388..31f4c65b7b 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -431,29 +431,24 @@ Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid) } void getLocale(char* language, char* region) { + unsigned langlen = 0, reglen = 0; const char* LANG = getenv("LANG"); - char dummy = '\0'; - char* lang = &dummy; - char* reg = &dummy; - if (LANG) { - unsigned underscore = 0; - while (underscore < strlen(LANG) && *(LANG + underscore) != '_') ++underscore; - unsigned period = underscore + 1; - while (period < strlen(LANG) && *(LANG + period) != '.') ++period; - - unsigned reglen = period - underscore - 1; - char lang_[underscore + 1]; lang = lang_; - char reg_[reglen + 1]; reg = reg_; - - memcpy(lang, LANG, underscore * sizeof(char)); - memcpy(reg, LANG + underscore + 1, reglen * sizeof(char)); - lang[underscore] = reg[reglen] = '\0'; + while (langlen < strlen(LANG) && *(LANG + langlen) != '_') ++langlen; + unsigned regend = langlen + 1; + while (regend < strlen(LANG) && *(LANG + regend) != '.') ++regend; + reglen = regend - langlen - 1; } - if (language) memcpy(language, lang, (strlen(lang) + 1) * sizeof(char)); - if (region) memcpy(region, reg, (strlen(reg) + 1) * sizeof(char)); + if (language) { + memcpy(language, LANG, langlen * sizeof(char)); + language[langlen] = '\0'; + } + if (region) { + memcpy(region, LANG + langlen + 1, reglen * sizeof(char)); + region[reglen] = '\0'; + } } #endif From cddc305a759c630beead7ea184fc7f773fcc89e8 Mon Sep 17 00:00:00 2001 From: jet Date: Thu, 7 Oct 2010 16:32:59 -0600 Subject: [PATCH 04/11] Locale error checking is now more robust. --- classpath/java-lang.cpp | 120 +++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 32 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 31f4c65b7b..415ad9301e 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -18,6 +18,7 @@ #include "jni-util.h" #include "errno.h" #include "fcntl.h" +#include "ctype.h" #ifdef PLATFORM_WINDOWS @@ -132,6 +133,59 @@ namespace { #endif } +class Locale { + static const unsigned MINLEN = 2; + static const unsigned MAXLEN = 3; + static const unsigned FIELDSIZE = MAXLEN + 1; + + static const char* DEFAULT_LANGUAGE; + static const char* DEFAULT_REGION; + + char language[FIELDSIZE]; + char region[FIELDSIZE]; + + bool isLanguage(const char* language) { + if (!language) return false; + unsigned len = strlen(language); + if (len < MINLEN || len > MAXLEN) return false; + const char* p = language - 1; + while (islower(*++p)); + if (*p != '\0') return false; + return true; + } + + bool isRegion(const char* region) { + if (!region) return false; + unsigned len = strlen(region); + if ((len != 0 && len < MINLEN) || len > MAXLEN) return false; + const char* p = region - 1; + while (isupper(*++p)); + if (*p != '\0') return false; + return true; + } + +public: + Locale(const char* language = "", const char* region = "") { + if (!isLanguage(language) || !isRegion(region)) { + language = DEFAULT_LANGUAGE; + region = DEFAULT_REGION; + } + memcpy(this->language, language, strlen(language) + 1); + memcpy(this->region, region, strlen(region) + 1); + } + + Locale& operator=(const Locale& l) { + memcpy(language, l.language, FIELDSIZE); + memcpy(region, l.region, FIELDSIZE); + return *this; + } + + const char* getLanguage() { return reinterpret_cast(language); } + const char* getRegion() { return reinterpret_cast(region); } +}; +const char* Locale::DEFAULT_LANGUAGE = "en"; +const char* Locale::DEFAULT_REGION = ""; + #ifdef PLATFORM_WINDOWS extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, @@ -230,14 +284,12 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid) return exitCode; } -void getLocale(char* language, char* region) { - const char dummy = '\0'; - const char* lang = &dummy; - const char* reg = &dummy; - - unsigned locale = GetUserDefaultUILanguage(); - unsigned prilang = locale & 0x3ff; - unsigned sublang = locale >> 10; +Locale getLocale() { + const char* lang = ""; + const char* reg = ""; + unsigned langid = GetUserDefaultUILanguage(); + unsigned prilang = langid & 0x3ff; + unsigned sublang = langid >> 10; switch (prilang) { case 0x004: { @@ -301,10 +353,11 @@ void getLocale(char* language, char* region) { case 0x018: lang = "ro"; reg = "RO"; break; case 0x019: lang = "ru"; reg = "RU"; break; case 0x01d: lang = "sv"; reg = "SE"; break; + default: lang = "en"; } - if (language) memcpy(language, lang, (strlen(lang) + 1) * sizeof(char)); - if (region) memcpy(region, reg, (strlen(reg) + 1) * sizeof(char)); + Locale locale(lang, reg); + return locale; } #else extern "C" JNIEXPORT void JNICALL @@ -430,25 +483,30 @@ Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid) return exitCode; } -void getLocale(char* language, char* region) { - unsigned langlen = 0, reglen = 0; +Locale getLocale() { + Locale fallback; + const char* LANG = getenv("LANG"); + if (!LANG || strcmp(LANG, "C") == 0) return fallback; - if (LANG) { - while (langlen < strlen(LANG) && *(LANG + langlen) != '_') ++langlen; - unsigned regend = langlen + 1; - while (regend < strlen(LANG) && *(LANG + regend) != '.') ++regend; - reglen = regend - langlen - 1; - } + int len = strlen(LANG); + char buf[len]; + memcpy(buf, LANG, len); - if (language) { - memcpy(language, LANG, langlen * sizeof(char)); - language[langlen] = '\0'; - } - if (region) { - memcpy(region, LANG + langlen + 1, reglen * sizeof(char)); - region[reglen] = '\0'; - } + char* tracer = buf; + const char* reg; + + while (*tracer && *tracer != '_') ++tracer; + if (!*tracer) return fallback; + *tracer = '\0'; + reg = tracer++ + 1; + + while (*tracer && *tracer != '.') ++tracer; + if (tracer == reg) return fallback; + *tracer = '\0'; + + Locale locale(buf, reg); + return locale; } #endif @@ -551,13 +609,11 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, } #endif else if (strcmp(chars, "user.language") == 0) { - char lang[16]; - getLocale(lang, 0); - if (strlen(lang)) r = e->NewStringUTF(lang); + Locale locale = getLocale(); + if (strlen(locale.getLanguage())) r = e->NewStringUTF(locale.getLanguage()); } else if (strcmp(chars, "user.region") == 0) { - char reg[16]; - getLocale(0, reg); - if (strlen(reg)) r = e->NewStringUTF(reg); + Locale locale = getLocale(); + if (strlen(locale.getRegion())) r = e->NewStringUTF(locale.getRegion()); } e->ReleaseStringUTFChars(name, chars); From 0713f8d5cb39c810e2eee57f2cd4ba01fb406fcf Mon Sep 17 00:00:00 2001 From: jet Date: Thu, 14 Oct 2010 16:20:41 -0600 Subject: [PATCH 05/11] Locale system changes to better mimic Sun's VM. --- classpath/java-lang.cpp | 32 +++++++++++++++++--------------- classpath/java/util/Locale.java | 10 ++++++++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 415ad9301e..3b2c0ed52b 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -133,10 +133,9 @@ namespace { #endif } -class Locale { - static const unsigned MINLEN = 2; - static const unsigned MAXLEN = 3; - static const unsigned FIELDSIZE = MAXLEN + 1; +class Locale { // represents an ISO two-char language/country pair + static const unsigned FIELDLEN = 2; + static const unsigned FIELDSIZE = FIELDLEN + 1; static const char* DEFAULT_LANGUAGE; static const char* DEFAULT_REGION; @@ -147,7 +146,7 @@ class Locale { bool isLanguage(const char* language) { if (!language) return false; unsigned len = strlen(language); - if (len < MINLEN || len > MAXLEN) return false; + if (len != FIELDLEN) return false; const char* p = language - 1; while (islower(*++p)); if (*p != '\0') return false; @@ -157,7 +156,7 @@ class Locale { bool isRegion(const char* region) { if (!region) return false; unsigned len = strlen(region); - if ((len != 0 && len < MINLEN) || len > MAXLEN) return false; + if (len != FIELDLEN) return false; const char* p = region - 1; while (isupper(*++p)); if (*p != '\0') return false; @@ -165,13 +164,16 @@ class Locale { } public: - Locale(const char* language = "", const char* region = "") { - if (!isLanguage(language) || !isRegion(region)) { - language = DEFAULT_LANGUAGE; - region = DEFAULT_REGION; - } - memcpy(this->language, language, strlen(language) + 1); - memcpy(this->region, region, strlen(region) + 1); + Locale(const char* language = "") { + Locale l(language, ""); + *this = l; + } + + Locale(const char* language, const char* region) { + language = isLanguage(language) ? language : DEFAULT_LANGUAGE; + region = isRegion(region) ? region : DEFAULT_REGION; + memcpy(this->language, language, FIELDSIZE); + memcpy(this->region, region, FIELDSIZE); } Locale& operator=(const Locale& l) { @@ -295,8 +297,8 @@ Locale getLocale() { case 0x004: { lang = "zh"; switch (sublang) { - case 0x01: reg = "Hant"; break; - case 0x02: reg = "Hans"; break; + case 0x01: reg = "CN"; break; + case 0x02: reg = "TW"; break; case 0x03: reg = "HK"; break; case 0x04: reg = "SG"; break; } diff --git a/classpath/java/util/Locale.java b/classpath/java/util/Locale.java index c53b6f4ed1..8c756ff406 100644 --- a/classpath/java/util/Locale.java +++ b/classpath/java/util/Locale.java @@ -11,12 +11,18 @@ package java.util; public class Locale { - public static final Locale ENGLISH = new Locale("en", "us"); + private static final Locale DEFAULT; + public static final Locale ENGLISH = new Locale("en", ""); private final String language; private final String country; private final String variant; + static { + DEFAULT = new Locale(System.getProperty("user.language"), + System.getProperty("user.region")); + } + public Locale(String language, String country, String variant) { this.language = language; this.country = country; @@ -44,6 +50,6 @@ public class Locale { } public static Locale getDefault() { - return ENGLISH; + return DEFAULT; } } From 8c54446c67e2edef7b4aacc7661b4596f99816a6 Mon Sep 17 00:00:00 2001 From: JET Date: Mon, 8 Nov 2010 09:47:46 -0700 Subject: [PATCH 06/11] Fixed minor compiler warnings. --- classpath/java-lang.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 3b2c0ed52b..59f7acc8da 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -148,7 +148,7 @@ class Locale { // represents an ISO two-char language/country pair unsigned len = strlen(language); if (len != FIELDLEN) return false; const char* p = language - 1; - while (islower(*++p)); + while (islower(*++p)) ; if (*p != '\0') return false; return true; } @@ -158,7 +158,7 @@ class Locale { // represents an ISO two-char language/country pair unsigned len = strlen(region); if (len != FIELDLEN) return false; const char* p = region - 1; - while (isupper(*++p)); + while (isupper(*++p)) ; if (*p != '\0') return false; return true; } From 7270eb78790994fef8c42215bcd363d7c613a9d6 Mon Sep 17 00:00:00 2001 From: JET Date: Wed, 15 Dec 2010 15:18:43 -0700 Subject: [PATCH 07/11] Fixed behavior of Locale and implemented its toString(). --- classpath/java/util/Locale.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/classpath/java/util/Locale.java b/classpath/java/util/Locale.java index 8c756ff406..373506bdec 100644 --- a/classpath/java/util/Locale.java +++ b/classpath/java/util/Locale.java @@ -30,11 +30,11 @@ public class Locale { } public Locale(String language, String country) { - this(language, country, null); + this(language, country, ""); } public Locale(String language) { - this(language, null); + this(language, ""); } public String getLanguage() { @@ -52,4 +52,13 @@ public class Locale { public static Locale getDefault() { return DEFAULT; } + + public final String toString() { + boolean hasLanguage = language != ""; + boolean hasCountry = country != ""; + boolean hasVariant = variant != ""; + + if (!hasLanguage && !hasCountry) return ""; + return language + (hasCountry || hasVariant ? '_' + country : "") + (hasVariant ? '_' + variant : ""); + } } From 98166dcc61488f949235406e63d1ad6bbbe2dc3e Mon Sep 17 00:00:00 2001 From: JET Date: Tue, 21 Dec 2010 11:39:26 -0700 Subject: [PATCH 08/11] ASCII escapes in property files are now parsed, albeit crudely. --- classpath/java/util/Properties.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/classpath/java/util/Properties.java b/classpath/java/util/Properties.java index a09ba77808..b67d783c67 100644 --- a/classpath/java/util/Properties.java +++ b/classpath/java/util/Properties.java @@ -137,6 +137,19 @@ public class Properties extends Hashtable { } break; + case 'u': + if (escaped) { // ASCII Unicode escape + int most = Character.digit((char)in.read(), 16); + int more = Character.digit((char)in.read(), 16); + int less = Character.digit((char)in.read(), 16); + int least = Character.digit((char)in.read(), 16); + char utf16 = (char)(most << 12 | more << 8 | less << 4 | least); + append(utf16); + } else { + append(c); + } + break; + default: append(c); break; From 422263f499c3d17166c9563da7b34095b0d18521 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 22 Feb 2011 15:45:46 -0700 Subject: [PATCH 09/11] fix Mac OS PowerPC cross build While we can use Linux's jni.h to cross compile the i386 Mac OS build, that doesn't work for the PowerPC one. Now we use the proper /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Headers/jni.h from the sysroot instead. --- makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 811a14ceb4..ccd6c8ada9 100644 --- a/makefile +++ b/makefile @@ -219,13 +219,14 @@ ifeq ($(platform),darwin) ar = i686-apple-darwin8-ar ranlib = i686-apple-darwin8-ranlib strip = i686-apple-darwin8-strip - extra-cflags = -I$(JAVA_HOME)/include/linux + sysroot = /opt/mac/SDKs/MacOSX10.4u.sdk + cflags = -I$(sysroot)/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Headers/ \ + $(common-cflags) -fPIC -fvisibility=hidden -I$(src) else + build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) build-lflags += -framework CoreFoundation endif - build-cflags = $(common-cflags) $(extra-cflags) -fPIC -fvisibility=hidden \ - -I$(src) version-script-flag = lflags = $(common-lflags) -ldl -framework CoreFoundation \ -framework CoreServices From 5b830343ba4f879732d45e6d437bc8ff421c07be Mon Sep 17 00:00:00 2001 From: JET Date: Wed, 23 Mar 2011 17:06:33 -0600 Subject: [PATCH 10/11] Properties.java UTF-16 support refactoring. --- classpath/java/util/Properties.java | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/classpath/java/util/Properties.java b/classpath/java/util/Properties.java index c37de95878..10b5c90687 100644 --- a/classpath/java/util/Properties.java +++ b/classpath/java/util/Properties.java @@ -85,7 +85,18 @@ public class Properties extends Hashtable { } abstract int readCharacter() throws IOException; - + + char readUtf16() throws IOException { + char c = 0; + for (int i = 0; i < 4; ++i) { + int digit = Character.digit((char)readCharacter(), 16); + if (digit == -1) throw new IOException("Invalid Unicode escape encountered."); + c <<= 4; + c |= digit; + } + return c; + } + void parse(Map map) throws IOException { @@ -149,17 +160,11 @@ public class Properties extends Hashtable { break; case 'u': - if (escaped) { // ASCII Unicode escape - int most = Character.digit((char)in.read(), 16); - int more = Character.digit((char)in.read(), 16); - int less = Character.digit((char)in.read(), 16); - int least = Character.digit((char)in.read(), 16); - char utf16 = (char)(most << 12 | more << 8 | less << 4 | least); - append(utf16); + if (escaped) { + append(readUtf16()); } else { append(c); - } - break; + } break; default: append(c); From 706f9d91ad8b336db9ba6e32a1942200e0efb412 Mon Sep 17 00:00:00 2001 From: JET Date: Tue, 5 Apr 2011 15:13:29 -0600 Subject: [PATCH 11/11] Fixed bug with *nix LANG var region parsing. --- classpath/java-lang.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 48fdacc01a..779682c8c0 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -471,8 +471,8 @@ Locale getLocale() { if (!LANG || strcmp(LANG, "C") == 0) return fallback; int len = strlen(LANG); - char buf[len]; - memcpy(buf, LANG, len); + char buf[len + 1]; // + 1 for the '\0' char + memcpy(buf, LANG, len + 1); char* tracer = buf; const char* reg; @@ -480,7 +480,7 @@ Locale getLocale() { while (*tracer && *tracer != '_') ++tracer; if (!*tracer) return fallback; *tracer = '\0'; - reg = tracer++ + 1; + reg = ++tracer; while (*tracer && *tracer != '.') ++tracer; if (tracer == reg) return fallback;