8246632: StringConcatFactory::makeConcatWithConstants no longer throws NullPointerException when an unexpected constant is null

Reviewed-by: rriggs, mchung
This commit is contained in:
Claes Redestad 2020-06-08 19:23:51 +02:00
parent 5805cbeaaf
commit a043bd0ff8
2 changed files with 24 additions and 16 deletions

View file

@ -329,6 +329,10 @@ public final class StringConcatFactory {
Objects.requireNonNull(concatType, "Concat type is null"); Objects.requireNonNull(concatType, "Concat type is null");
Objects.requireNonNull(constants, "Constants are null"); Objects.requireNonNull(constants, "Constants are null");
for (Object o : constants) {
Objects.requireNonNull(o, "Cannot accept null constants");
}
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) { if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
throw new StringConcatException("Invalid caller: " + throw new StringConcatException("Invalid caller: " +
lookup.lookupClass().getName()); lookup.lookupClass().getName());
@ -382,11 +386,11 @@ public final class StringConcatFactory {
if (c == TAG_CONST) { if (c == TAG_CONST) {
if (cCount == constants.length) { if (cCount == constants.length) {
// Not enough constants // Not enough constants
throw constantMismatch(concatType, oCount); throw constantMismatch(constants, cCount);
} }
// Accumulate constant args along with any constants encoded // Accumulate constant args along with any constants encoded
// into the recipe // into the recipe
acc.append(Objects.requireNonNull(constants[cCount++], "Cannot accept null constants")); acc.append(constants[cCount++]);
} else if (c == TAG_ARG) { } else if (c == TAG_ARG) {
// Flush any accumulated characters into a constant // Flush any accumulated characters into a constant
if (acc.length() > 0) { if (acc.length() > 0) {
@ -406,28 +410,32 @@ public final class StringConcatFactory {
if (acc.length() > 0) { if (acc.length() > 0) {
elements.add(acc.toString()); elements.add(acc.toString());
} }
if (oCount != concatType.parameterCount()) { if (oCount != concatType.parameterCount()) {
throw constantMismatch(concatType, oCount); throw argumentMismatch(concatType, oCount);
} }
if (cCount != constants.length) { if (cCount < constants.length) {
throw new StringConcatException( throw constantMismatch(constants, cCount);
"Mismatched number of concat constants: recipe wants " +
cCount +
" constants, but only " +
constants.length +
" are passed");
} }
return elements; return elements;
} }
private static StringConcatException constantMismatch(MethodType concatType, private static StringConcatException argumentMismatch(MethodType concatType,
int oCount) { int oCount) {
return new StringConcatException( return new StringConcatException(
"Mismatched number of concat arguments: recipe wants " + "Mismatched number of concat arguments: recipe wants " +
oCount + oCount +
" arguments, but signature provides " + " arguments, but signature provides " +
concatType.parameterCount()); concatType.parameterCount());
}
private static StringConcatException constantMismatch(Object[] constants,
int cCount) {
return new StringConcatException(
"Mismatched number of concat constants: recipe wants " +
cCount +
" constants, but only " +
constants.length +
" are passed");
} }
/** /**

View file

@ -220,7 +220,7 @@ public class StringConcatFactoryInvariants {
fail("Static arguments and recipe mismatch: too many", fail("Static arguments and recipe mismatch: too many",
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz")); () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz"));
fail("Static arguments and recipe mismatch, too many, overflowing constant is null", failNPE("Static arguments and recipe mismatch, too many, overflowing constant is null",
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", null)); () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", null));
// Advanced factory: check for mismatched recipe and dynamic arguments // Advanced factory: check for mismatched recipe and dynamic arguments