mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-09 23:50:22 +00:00
8379334: jpackage: fix bug in DottedVersion.greedy() function
Reviewed-by: almatvee
This commit is contained in:
parent
f266079d26
commit
c2f6bd87c6
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2026, 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
|
||||
@ -37,12 +37,11 @@ import java.util.stream.Stream;
|
||||
public final class DottedVersion {
|
||||
|
||||
private DottedVersion(String version, boolean greedy) {
|
||||
this.value = version;
|
||||
if (version.isEmpty()) {
|
||||
if (greedy) {
|
||||
throw new IllegalArgumentException(I18N.getString("error.version-string-empty"));
|
||||
} else {
|
||||
this.components = new BigInteger[0];
|
||||
this.components = new Component[0];
|
||||
this.suffix = "";
|
||||
}
|
||||
} else {
|
||||
@ -53,12 +52,12 @@ public final class DottedVersion {
|
||||
if (!greedy) {
|
||||
return null;
|
||||
} else {
|
||||
ds.throwException();
|
||||
throw ds.createException();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return new BigInteger(digits);
|
||||
return new Component(digits);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (!greedy) {
|
||||
return null;
|
||||
@ -68,17 +67,25 @@ public final class DottedVersion {
|
||||
digits));
|
||||
}
|
||||
}
|
||||
}).takeWhile(Objects::nonNull).toArray(BigInteger[]::new);
|
||||
}).takeWhile(Objects::nonNull).toArray(Component[]::new);
|
||||
suffix = ds.getUnprocessedString();
|
||||
if (!suffix.isEmpty() && greedy) {
|
||||
ds.throwException();
|
||||
throw ds.createException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DottedVersion(Component[] components, String suffix) {
|
||||
this.components = components;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
private static class DigitsSupplier {
|
||||
|
||||
DigitsSupplier(String input) {
|
||||
if (input.isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
@ -95,7 +102,7 @@ public final class DottedVersion {
|
||||
} else {
|
||||
var curStopAtDot = (chr == '.');
|
||||
if (!curStopAtDot) {
|
||||
if (lastDotPos >= 0) {
|
||||
if (sb.isEmpty() && lastDotPos >= 0) {
|
||||
cursor = lastDotPos;
|
||||
} else {
|
||||
cursor--;
|
||||
@ -112,11 +119,7 @@ public final class DottedVersion {
|
||||
}
|
||||
|
||||
if (sb.isEmpty()) {
|
||||
if (lastDotPos >= 0) {
|
||||
cursor = lastDotPos;
|
||||
} else {
|
||||
cursor--;
|
||||
}
|
||||
cursor = lastDotPos;
|
||||
}
|
||||
|
||||
stoped = true;
|
||||
@ -127,7 +130,7 @@ public final class DottedVersion {
|
||||
return input.substring(cursor);
|
||||
}
|
||||
|
||||
void throwException() {
|
||||
IllegalArgumentException createException() {
|
||||
final String tail;
|
||||
if (lastDotPos >= 0) {
|
||||
tail = input.substring(lastDotPos + 1);
|
||||
@ -143,7 +146,7 @@ public final class DottedVersion {
|
||||
errMessage = MessageFormat.format(I18N.getString(
|
||||
"error.version-string-invalid-component"), input, tail);
|
||||
}
|
||||
throw new IllegalArgumentException(errMessage);
|
||||
return new IllegalArgumentException(errMessage);
|
||||
}
|
||||
|
||||
private int cursor;
|
||||
@ -211,9 +214,31 @@ public final class DottedVersion {
|
||||
return Arrays.deepEquals(this.components, other.components);
|
||||
}
|
||||
|
||||
public DottedVersion trim(int limit) {
|
||||
if (limit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (limit >= components.length) {
|
||||
return this;
|
||||
} else {
|
||||
return new DottedVersion(Arrays.copyOf(components, limit), suffix);
|
||||
}
|
||||
}
|
||||
|
||||
public DottedVersion pad(int limit) {
|
||||
if (limit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (limit <= components.length) {
|
||||
return this;
|
||||
} else {
|
||||
var newComponents = Arrays.copyOf(components, limit);
|
||||
Arrays.fill(newComponents, components.length, newComponents.length, Component.ZERO);
|
||||
return new DottedVersion(newComponents, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
return Stream.of(components).map(Component::toString).collect(Collectors.joining(".")) + suffix;
|
||||
}
|
||||
|
||||
public String getUnprocessedSuffix() {
|
||||
@ -221,14 +246,35 @@ public final class DottedVersion {
|
||||
}
|
||||
|
||||
public String toComponentsString() {
|
||||
return Stream.of(components).map(BigInteger::toString).collect(Collectors.joining("."));
|
||||
return Stream.of(components).map(Component::parsedValue).map(BigInteger::toString).collect(Collectors.joining("."));
|
||||
}
|
||||
|
||||
public int getComponentsCount() {
|
||||
return components.length;
|
||||
}
|
||||
|
||||
public BigInteger[] getComponents() {
|
||||
return components;
|
||||
return Stream.of(components).map(Component::parsedValue).toArray(BigInteger[]::new);
|
||||
}
|
||||
|
||||
private final BigInteger[] components;
|
||||
private final String value;
|
||||
private record Component(BigInteger parsedValue, String strValue) {
|
||||
Component {
|
||||
Objects.requireNonNull(parsedValue);
|
||||
Objects.requireNonNull(strValue);
|
||||
}
|
||||
|
||||
Component(String strValue) {
|
||||
this(new BigInteger(strValue), strValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return strValue;
|
||||
}
|
||||
|
||||
static final Component ZERO = new Component(BigInteger.ZERO, "0");
|
||||
}
|
||||
|
||||
private final Component[] components;
|
||||
private final String suffix;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2026, 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
|
||||
@ -32,8 +32,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@ -108,12 +111,113 @@ public class DottedVersionTest {
|
||||
TestConfig.lazy("+1", "+1", 0, ""),
|
||||
TestConfig.lazy("-1", "-1", 0, ""),
|
||||
TestConfig.lazy("-0", "-0", 0, ""),
|
||||
TestConfig.lazy("+0", "+0", 0, "")
|
||||
TestConfig.lazy("+0", "+0", 0, ""),
|
||||
TestConfig.lazy("+0", "+0", 0, ""),
|
||||
TestConfig.lazy("1.2.3+ea", "+ea", 3, "1.2.3"),
|
||||
TestConfig.lazy(".7", ".7", 0, ""),
|
||||
TestConfig.lazy(".+7", ".+7", 0, "")
|
||||
));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testTrim(DottedVersion ver, String expectedStr, int limit) {
|
||||
var expected = DottedVersion.lazy(expectedStr);
|
||||
var actual = ver.trim(limit);
|
||||
assertEquals(expected, actual);
|
||||
if (limit >= ver.getComponents().length) {
|
||||
assertSame(ver, actual);
|
||||
} else {
|
||||
assertNotSame(ver, actual);
|
||||
}
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testTrimNegative(DottedVersion ver, int limit) {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> {
|
||||
ver.trim(limit);
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testTrim() {
|
||||
|
||||
var testCases = new ArrayList<Arguments>();
|
||||
|
||||
for (var suffix : List.of("", ".foo", "-ea", "+345")) {
|
||||
testCases.addAll(List.of(
|
||||
Arguments.of("1.02.3" + suffix, "" + suffix, 0),
|
||||
Arguments.of("1.02.3" + suffix, "1" + suffix, 1),
|
||||
Arguments.of("1.02.3" + suffix, "1.02" + suffix, 2),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 3),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 4)
|
||||
));
|
||||
}
|
||||
|
||||
return testCases.stream().map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testTrimNegative() {
|
||||
return Stream.of(
|
||||
Arguments.of("10.5.foo", -1)
|
||||
).map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPad(DottedVersion ver, String expectedStr, int limit) {
|
||||
var expected = DottedVersion.lazy(expectedStr);
|
||||
var actual = ver.pad(limit);
|
||||
assertEquals(expected, actual);
|
||||
if (limit <= ver.getComponents().length) {
|
||||
assertSame(ver, actual);
|
||||
} else {
|
||||
assertNotSame(ver, actual);
|
||||
}
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void testPadNegative(DottedVersion ver, int limit) {
|
||||
assertThrowsExactly(IllegalArgumentException.class, () -> {
|
||||
ver.pad(limit);
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testPad() {
|
||||
|
||||
var testCases = new ArrayList<Arguments>();
|
||||
|
||||
for (var suffix : List.of("", ".foo", "-ea", "+345")) {
|
||||
testCases.addAll(List.of(
|
||||
Arguments.of("" + suffix, "" + suffix, 0),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3" + suffix, 0),
|
||||
Arguments.of("" + suffix, "0" + suffix, 1),
|
||||
Arguments.of("1" + suffix, "1" + suffix, 1),
|
||||
Arguments.of("1" + suffix, "1.0" + suffix, 2),
|
||||
Arguments.of("1.02.3" + suffix, "1.02.3.0.0" + suffix, 5)
|
||||
));
|
||||
}
|
||||
|
||||
return testCases.stream().map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testPadNegative() {
|
||||
return Stream.of(
|
||||
Arguments.of("10.5.foo", -1)
|
||||
).map(DottedVersionTest::mapFirstStringToDottedVersion);
|
||||
}
|
||||
|
||||
private static Arguments mapFirstStringToDottedVersion(Arguments v) {
|
||||
var objs = v.get();
|
||||
objs[0] = DottedVersion.lazy((String)objs[0]);
|
||||
return Arguments.of(objs);
|
||||
}
|
||||
|
||||
record InvalidVersionTestSpec(String version, String invalidComponent) {
|
||||
public InvalidVersionTestSpec {
|
||||
Objects.requireNonNull(version);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user