diff --git a/src/share/classes/java/lang/String.java b/src/share/classes/java/lang/String.java index 0b1d55bcd0af7f66903e3ac06620e43926bde357..ea27b357ebd09d87497aeb4bc04f554c01f35cb7 100644 --- a/src/share/classes/java/lang/String.java +++ b/src/share/classes/java/lang/String.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -987,7 +987,8 @@ public final class String /** * Compares this string to the specified {@code StringBuffer}. The result * is {@code true} if and only if this {@code String} represents the same - * sequence of characters as the specified {@code StringBuffer}. + * sequence of characters as the specified {@code StringBuffer}. This method + * synchronizes on the {@code StringBuffer}. * * @param sb * The {@code StringBuffer} to compare this {@code String} against @@ -999,15 +1000,29 @@ public final class String * @since 1.4 */ public boolean contentEquals(StringBuffer sb) { - synchronized (sb) { - return contentEquals((CharSequence) sb); + return contentEquals((CharSequence) sb); + } + + private boolean nonSyncContentEquals(AbstractStringBuilder sb) { + char v1[] = value; + char v2[] = sb.getValue(); + int i = 0; + int n = value.length; + while (n-- != 0) { + if (v1[i] != v2[i]) { + return false; + } + i++; } + return true; } /** - * Compares this string to the specified {@code CharSequence}. The result - * is {@code true} if and only if this {@code String} represents the same - * sequence of char values as the specified sequence. + * Compares this string to the specified {@code CharSequence}. The + * result is {@code true} if and only if this {@code String} represents the + * same sequence of char values as the specified sequence. Note that if the + * {@code CharSequence} is a {@code StringBuffer} then the method + * synchronizes on it. * * @param cs * The sequence to compare this {@code String} against @@ -1023,16 +1038,13 @@ public final class String return false; // Argument is a StringBuffer, StringBuilder if (cs instanceof AbstractStringBuilder) { - char v1[] = value; - char v2[] = ((AbstractStringBuilder) cs).getValue(); - int i = 0; - int n = value.length; - while (n-- != 0) { - if (v1[i] != v2[i]) - return false; - i++; + if (cs instanceof StringBuffer) { + synchronized(cs) { + return nonSyncContentEquals((AbstractStringBuilder)cs); + } + } else { + return nonSyncContentEquals((AbstractStringBuilder)cs); } - return true; } // Argument is a String if (cs.equals(this)) diff --git a/src/solaris/native/java/lang/java_props_md.c b/src/solaris/native/java/lang/java_props_md.c index a8022f945ba4eca389367d10e21e8163fe6e83ca..87562c8dbbe82084969407c990fbde7dc764e5a5 100644 --- a/src/solaris/native/java/lang/java_props_md.c +++ b/src/solaris/native/java/lang/java_props_md.c @@ -135,12 +135,12 @@ setPathEnvironment(char *envstring) #define P_tmpdir "/var/tmp" #endif -static int ParseLocale(int cat, char ** std_language, char ** std_script, +static int ParseLocale(JNIEnv* env, int cat, char ** std_language, char ** std_script, char ** std_country, char ** std_variant, char ** std_encoding) { - char temp[64]; + char *temp = NULL; char *language = NULL, *country = NULL, *variant = NULL, *encoding = NULL; - char *p, encoding_variant[64]; + char *p, *encoding_variant; char *lc; /* Query the locale set for the category */ @@ -156,6 +156,12 @@ static int ParseLocale(int cat, char ** std_language, char ** std_script, return 0; } + temp = malloc(strlen(lc) + 1); + if (temp == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } + if (cat == LC_CTYPE) { /* * Workaround for Solaris bug 4201684: Xlib doesn't like @euro @@ -178,6 +184,13 @@ static int ParseLocale(int cat, char ** std_language, char ** std_script, if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) { lc = "en_US"; } + + temp = malloc(strlen(lc) + 1); + if (temp == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } + #endif /* @@ -203,6 +216,13 @@ static int ParseLocale(int cat, char ** std_language, char ** std_script, * to a default country if that's possible. It's also used to map * the Solaris locale aliases to their proper Java locale IDs. */ + + encoding_variant = malloc(strlen(temp)+1); + if (encoding_variant == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } + if ((p = strchr(temp, '.')) != NULL) { strcpy(encoding_variant, p); /* Copy the leading '.' */ *p = '\0'; @@ -214,7 +234,17 @@ static int ParseLocale(int cat, char ** std_language, char ** std_script, } if (mapLookup(locale_aliases, temp, &p)) { + temp = realloc(temp, strlen(p)+1); + if (temp == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } strcpy(temp, p); + encoding_variant = realloc(encoding_variant, strlen(temp)+1); + if (encoding_variant == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return 0; + } // check the "encoding_variant" again, if any. if ((p = strchr(temp, '.')) != NULL) { strcpy(encoding_variant, p); /* Copy the leading '.' */ @@ -326,6 +356,9 @@ static int ParseLocale(int cat, char ** std_language, char ** std_script, #endif } + free(temp); + free(encoding_variant); + return 1; } @@ -480,13 +513,13 @@ GetJavaProperties(JNIEnv *env) * and store these in the user.language, user.country, user.variant and * file.encoding system properties. */ setlocale(LC_ALL, ""); - if (ParseLocale(LC_CTYPE, + if (ParseLocale(env, LC_CTYPE, &(sprops.format_language), &(sprops.format_script), &(sprops.format_country), &(sprops.format_variant), &(sprops.encoding))) { - ParseLocale(LC_MESSAGES, + ParseLocale(env, LC_MESSAGES, &(sprops.language), &(sprops.script), &(sprops.country),