Skip to content

Commit

Permalink
Merge pull request #19294 from pshipton/latin0.44.45
Browse files Browse the repository at this point in the history
(0.45) Fix String creation to treat a modified UTF8 zero as ASCII
  • Loading branch information
keithc-ca authored Apr 10, 2024
2 parents 3406f22 + 27edb76 commit 04eaa4d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
53 changes: 47 additions & 6 deletions runtime/gc_base/StringTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s
bool anonClassName = J9_ARE_ANY_BITS_SET(stringFlags, J9_STR_ANON_CLASS_NAME);
bool internString = J9_ARE_ANY_BITS_SET(stringFlags, J9_STR_INTERN);
UDATA unicodeLength = 0;
UDATA zerosFound = 0;

Trc_MM_createJavaLangString_Entry(vmThread, length, data, stringFlags);

Expand Down Expand Up @@ -596,6 +597,12 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s
} else {
for (UDATA i = 0; i < length; ++i) {
if (data[i] > 0x7F) {
/* Check for 0 in modified UTF8. */
if ((0xC0 == data[i]) && ((i + 1) < length) && (0x80 == data[i + 1])) {
zerosFound += 1;
i += 1;
continue;
}
isASCII = false;
if (compressStrings && (J2SE_VERSION(vm) >= J2SE_V17)) {
U_8 *dataTmp = data + i;
Expand Down Expand Up @@ -623,7 +630,13 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s

if (isASCII) {
for (UDATA i = 0; i < length; ++i) {
hash = (hash << 5) - hash + data[i];
U_8 c = data[i];
/* Look for the start of the modified UTF8 sequence for 0, which is validated when isASCII is set. */
if (0xC0 == c) {
c = 0;
i += 1;
}
hash = (hash << 5) - hash + c;
}
} else {
hash = VM_VMHelpers::computeHashForUTF8(data, length);
Expand Down Expand Up @@ -653,7 +666,7 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s

if (!isUnicode) {
if (isASCII) {
unicodeLength = length;
unicodeLength = length - zerosFound;
} else {
UDATA tempLength = length;
U_8 *tempData = data;
Expand Down Expand Up @@ -707,21 +720,35 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s
UDATA lastSlash = 0;
if (translateSlashes) {
if (isASCII) {
UDATA storeIndex = 0;
for (UDATA i = 0; i < length; ++i) {
U_8 c = data[i];
if ('/' == c) {
lastSlash = i;
c = '.';
/* Look for the start of the modified UTF8 sequence for 0, which is validated when isASCII is set. */
} else if (0xC0 == c) {
c = 0;
i += 1;
}
J9JAVAARRAYOFBYTE_STORE(vmThread, charArray, i, c);
J9JAVAARRAYOFBYTE_STORE(vmThread, charArray, storeIndex, c);
storeIndex += 1;
}
} else {
lastSlash = storeLatin1ByteArrayhelper(vmThread, data, length, charArray, true);
}
} else {
if (isASCII) {
UDATA storeIndex = 0;
for (UDATA i = 0; i < length; ++i) {
J9JAVAARRAYOFBYTE_STORE(vmThread, charArray, i, data[i]);
U_8 c = data[i];
/* Look for the start of the modified UTF8 sequence for 0, which is validated when isASCII is set. */
if (0xC0 == c) {
c = 0;
i += 1;
}
J9JAVAARRAYOFBYTE_STORE(vmThread, charArray, storeIndex, c);
storeIndex += 1;
}
} else {
lastSlash = storeLatin1ByteArrayhelper(vmThread, data, length, charArray, false);
Expand All @@ -738,17 +765,31 @@ j9gc_createJavaLangString(J9VMThread *vmThread, U_8 *data, UDATA length, UDATA s
UDATA lastSlash = 0;
if (isASCII) {
if (translateSlashes) {
IDATA storeIndex = 0;
for (UDATA i = 0; i < length; ++i) {
U_8 c = data[i];
if ('/' == c) {
lastSlash = i;
c = '.';
/* Look for the start of the modified UTF8 sequence for 0, which is validated when isASCII is set. */
} else if (0xC0 == c) {
c = 0;
i += 1;
}
J9JAVAARRAYOFCHAR_STORE(vmThread, charArray, i, c);
J9JAVAARRAYOFCHAR_STORE(vmThread, charArray, storeIndex, c);
storeIndex += 1;
}
} else {
UDATA storeIndex = 0;
for (UDATA i = 0; i < length; ++i) {
J9JAVAARRAYOFCHAR_STORE(vmThread, charArray, i, data[i]);
U_8 c = data[i];
/* Look for the start of the modified UTF8 sequence for 0, which is validated when isASCII is set. */
if (0xC0 == c) {
c = 0;
i += 1;
}
J9JAVAARRAYOFCHAR_STORE(vmThread, charArray, storeIndex, c);
storeIndex += 1;
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,11 @@ public void test_lastIndexOf2() {
public void test_lastIndexOf3() {
AssertJUnit.assertTrue("Returned incorrect index", hw1.lastIndexOf("World") == 5);
AssertJUnit.assertTrue("Found String outside of index", hw1.lastIndexOf("HeKKKKKKKK") == -1);

/* test https://github.com/eclipse-openj9/openj9/issues/19273 */
String s1 = "a";
String s2 = "b";
AssertJUnit.assertTrue("Incorrect index of \\u0000", (s1 + "\u0000" + s2).lastIndexOf("\u0000") == 1);
}

/**
Expand Down

0 comments on commit 04eaa4d

Please sign in to comment.