6914123: (str) Missing synchronization in java.lang.String#contentEquals(CharSequence)

Change contentEquals( CharSequence cs ) to do synchronization if cs is a StringBuffer

Reviewed-by: mduigou
This commit is contained in:
Jim Gish 2012-07-27 16:17:11 -04:00 committed by Jim Gish
parent 47403da7be
commit 558e1362a9

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * Compares this string to the specified {@code StringBuffer}. The result
* is {@code true} if and only if this {@code String} represents the same * 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 * @param sb
* The {@code StringBuffer} to compare this {@code String} against * The {@code StringBuffer} to compare this {@code String} against
@ -999,15 +1000,29 @@ public final class String
* @since 1.4 * @since 1.4
*/ */
public boolean contentEquals(StringBuffer sb) { 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 * Compares this string to the specified {@code CharSequence}. The
* is {@code true} if and only if this {@code String} represents the same * result is {@code true} if and only if this {@code String} represents the
* sequence of char values as the specified sequence. * 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 * @param cs
* The sequence to compare this {@code String} against * The sequence to compare this {@code String} against
@ -1023,16 +1038,13 @@ public final class String
return false; return false;
// Argument is a StringBuffer, StringBuilder // Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) { if (cs instanceof AbstractStringBuilder) {
char v1[] = value; if (cs instanceof StringBuffer) {
char v2[] = ((AbstractStringBuilder) cs).getValue(); synchronized(cs) {
int i = 0; return nonSyncContentEquals((AbstractStringBuilder)cs);
int n = value.length; }
while (n-- != 0) { } else {
if (v1[i] != v2[i]) return nonSyncContentEquals((AbstractStringBuilder)cs);
return false;
i++;
} }
return true;
} }
// Argument is a String // Argument is a String
if (cs.equals(this)) if (cs.equals(this))