This is an automated email from the ASF dual-hosted git repository.
terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new efd97c03d29 [ISSUE-39362] Fix from-x and to-y rejecting 0 as a valid
position (#39389)
efd97c03d29 is described below
commit efd97c03d294be02751e479770f852ce281839c2
Author: yali <[email protected]>
AuthorDate: Tue Aug 18 15:14:29 2026 +0800
[ISSUE-39362] Fix from-x and to-y rejecting 0 as a valid position (#39389)
* [ISSUE-39362] Add checkNotNegativeInteger for 0-based position validation
* [ISSUE-39362] Use checkNotNegativeInteger for from-x and to-y
* [ISSUE-39362] Use checkNotNegativeInteger for from-x and to-y
* [ISSUE-39362] Add zero and negative boundary tests for
checkNotNegativeInteger
* [ISSUE-39362] Add zero-from-x boundary test cases for MaskFromXToY
* [ISSUE-39362] Add zero-from-x boundary test cases for KeepFromXToY
* [ISSUE-39362] Fix expected values for KeepFromXToY zero-from-x tests
* [ISSUE-39362] Fix expected value for MaskFromXToY zero-from-x short case
---
.../algorithm/MaskAlgorithmPropertiesChecker.java | 18 +++++++++++++
.../algorithm/cover/KeepFromXToYMaskAlgorithm.java | 4 +--
.../algorithm/cover/MaskFromXToYMaskAlgorithm.java | 4 +--
.../MaskAlgorithmPropertiesCheckerTest.java | 30 ++++++++++++++++++++++
.../cover/KeepFromXToYMaskAlgorithmTest.java | 21 +++++++++++++++
.../cover/MaskFromXToYMaskAlgorithmTest.java | 21 +++++++++++++++
6 files changed, 94 insertions(+), 4 deletions(-)
diff --git
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesChecker.java
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesChecker.java
index cd5cc2ac02f..19f9ef53174 100644
---
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesChecker.java
+++
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesChecker.java
@@ -73,6 +73,24 @@ public final class MaskAlgorithmPropertiesChecker {
}
}
+ /**
+ * check not negative integer.
+ *
+ * @param props properties to be checked
+ * @param propKey properties key to be checked
+ * @param algorithm mask algorithm
+ * @throws AlgorithmInitializationException algorithm initialization
exception
+ */
+ public static void checkNotNegativeInteger(final Properties props, final
String propKey, final MaskAlgorithm<?, ?> algorithm) {
+ checkRequired(props, propKey, algorithm);
+ try {
+ int integerValue = Integer.parseInt(props.getProperty(propKey));
+ ShardingSpherePreconditions.checkState(integerValue >= 0, () ->
new AlgorithmInitializationException(algorithm, "%s must be a not negative
integer.", propKey));
+ } catch (final NumberFormatException ex) {
+ throw new AlgorithmInitializationException(algorithm, "%s must be
a valid integer number", propKey);
+ }
+ }
+
private static void checkRequired(final Properties props, final String
requiredPropKey, final MaskAlgorithm<?, ?> algorithm) {
ShardingSpherePreconditions.checkContainsKey(props, requiredPropKey,
() -> new AlgorithmInitializationException(algorithm, "%s is required",
requiredPropKey));
}
diff --git
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithm.java
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithm.java
index e96eaebe9b2..e897a104abf 100644
---
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithm.java
+++
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithm.java
@@ -52,12 +52,12 @@ public final class KeepFromXToYMaskAlgorithm implements
MaskAlgorithm<Object, St
}
private Integer createFromX(final Properties props) {
- MaskAlgorithmPropertiesChecker.checkPositiveInteger(props, FROM_X,
this);
+ MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, FROM_X,
this);
return Integer.parseInt(props.getProperty(FROM_X));
}
private Integer createToY(final Properties props) {
- MaskAlgorithmPropertiesChecker.checkPositiveInteger(props, TO_Y, this);
+ MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, TO_Y,
this);
return Integer.parseInt(props.getProperty(TO_Y));
}
diff --git
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithm.java
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithm.java
index eab93c67504..0b7cdc6ccf7 100644
---
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithm.java
+++
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithm.java
@@ -52,12 +52,12 @@ public final class MaskFromXToYMaskAlgorithm implements
MaskAlgorithm<Object, St
}
private Integer createFromX(final Properties props) {
- MaskAlgorithmPropertiesChecker.checkPositiveInteger(props, FROM_X,
this);
+ MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, FROM_X,
this);
return Integer.parseInt(props.getProperty(FROM_X));
}
private Integer createToY(final Properties props) {
- MaskAlgorithmPropertiesChecker.checkPositiveInteger(props, TO_Y, this);
+ MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, TO_Y,
this);
return Integer.parseInt(props.getProperty(TO_Y));
}
diff --git
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesCheckerTest.java
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesCheckerTest.java
index 4392f4512f5..7710c58e2a9 100644
---
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesCheckerTest.java
+++
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/MaskAlgorithmPropertiesCheckerTest.java
@@ -90,4 +90,34 @@ class MaskAlgorithmPropertiesCheckerTest {
Properties props = PropertiesBuilder.build(new Property("key",
"123.0"));
assertThrows(AlgorithmInitializationException.class, () ->
MaskAlgorithmPropertiesChecker.checkPositiveInteger(props, "key",
mock(MaskAlgorithm.class)));
}
+
+ @Test
+ void assertCheckNotNegativeIntegerSuccessWithPositive() {
+ Properties props = PropertiesBuilder.build(new Property("key", "123"));
+ assertDoesNotThrow(() ->
MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, "key",
mock(MaskAlgorithm.class)));
+ }
+
+ @Test
+ void assertCheckNotNegativeIntegerSuccessWithZero() {
+ Properties props = PropertiesBuilder.build(new Property("key", "0"));
+ assertDoesNotThrow(() ->
MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, "key",
mock(MaskAlgorithm.class)));
+ }
+
+ @Test
+ void assertCheckNotNegativeIntegerFailedWithoutKey() {
+ Properties props = new Properties();
+ assertThrows(AlgorithmInitializationException.class, () ->
MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, "key",
mock(MaskAlgorithm.class)));
+ }
+
+ @Test
+ void assertCheckNotNegativeIntegerFailedWithNegative() {
+ Properties props = PropertiesBuilder.build(new Property("key", "-1"));
+ assertThrows(AlgorithmInitializationException.class, () ->
MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, "key",
mock(MaskAlgorithm.class)));
+ }
+
+ @Test
+ void assertCheckNotNegativeIntegerFailedWithNotInteger() {
+ Properties props = PropertiesBuilder.build(new Property("key",
"123.0"));
+ assertThrows(AlgorithmInitializationException.class, () ->
MaskAlgorithmPropertiesChecker.checkNotNegativeInteger(props, "key",
mock(MaskAlgorithm.class)));
+ }
}
diff --git
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithmTest.java
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithmTest.java
index 08d9f941fcd..ef705faac0d 100644
---
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithmTest.java
+++
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/KeepFromXToYMaskAlgorithmTest.java
@@ -51,6 +51,12 @@ class KeepFromXToYMaskAlgorithmTest {
MaskAlgorithmAssertions.assertMask(type, props, plainValue,
maskedValue);
}
+ @ParameterizedTest(name = "{0}: {1}")
+ @ArgumentsSource(AlgorithmMaskExecuteWithZeroFromXArgumentsProvider.class)
+ void assertMaskWithZeroFromX(final String type,
@SuppressWarnings("unused") final String name, final Properties props, final
Object plainValue, final Object maskedValue) {
+ MaskAlgorithmAssertions.assertMask(type, props, plainValue,
maskedValue);
+ }
+
private static final class AlgorithmInitArgumentsProvider extends
MaskAlgorithmInitArgumentsProvider {
AlgorithmInitArgumentsProvider() {
@@ -106,4 +112,19 @@ class KeepFromXToYMaskAlgorithmTest {
new
MaskAlgorithmExecuteCaseAssert("plain_value_length_equals_to_Y_plus_one",
"abc123", "*****3"));
}
}
+
+ private static final class
AlgorithmMaskExecuteWithZeroFromXArgumentsProvider extends
MaskAlgorithmExecuteArgumentsProvider {
+
+ AlgorithmMaskExecuteWithZeroFromXArgumentsProvider() {
+ super("KEEP_FROM_X_TO_Y", PropertiesBuilder.build(new
Property("from-x", "0"), new Property("to-y", "2"), new
Property("replace-char", "*")));
+ }
+
+ @Override
+ protected Collection<MaskAlgorithmExecuteCaseAssert> getCaseAsserts() {
+ return Arrays.asList(
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_normal",
"abc123456", "abc******"),
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_short",
"ab", "ab"),
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_empty",
"", ""));
+ }
+ }
}
diff --git
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithmTest.java
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithmTest.java
index ced2c5aa852..59726f71492 100644
---
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithmTest.java
+++
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/algorithm/cover/MaskFromXToYMaskAlgorithmTest.java
@@ -51,6 +51,12 @@ class MaskFromXToYMaskAlgorithmTest {
MaskAlgorithmAssertions.assertMask(type, props, plainValue,
maskedValue);
}
+ @ParameterizedTest(name = "{0}: {1}")
+ @ArgumentsSource(AlgorithmMaskExecuteWithZeroFromXArgumentsProvider.class)
+ void assertMaskWithZeroFromX(final String type,
@SuppressWarnings("unused") final String name, final Properties props, final
Object plainValue, final Object maskedValue) {
+ MaskAlgorithmAssertions.assertMask(type, props, plainValue,
maskedValue);
+ }
+
private static final class AlgorithmInitArgumentsProvider extends
MaskAlgorithmInitArgumentsProvider {
AlgorithmInitArgumentsProvider() {
@@ -104,4 +110,19 @@ class MaskFromXToYMaskAlgorithmTest {
new
MaskAlgorithmExecuteCaseAssert("length_equals_to_Y_plus_one", "abc123",
"abc12*"));
}
}
+
+ private static final class
AlgorithmMaskExecuteWithZeroFromXArgumentsProvider extends
MaskAlgorithmExecuteArgumentsProvider {
+
+ AlgorithmMaskExecuteWithZeroFromXArgumentsProvider() {
+ super("MASK_FROM_X_TO_Y", PropertiesBuilder.build(new
Property("from-x", "0"), new Property("to-y", "2"), new
Property("replace-char", "*")));
+ }
+
+ @Override
+ protected Collection<MaskAlgorithmExecuteCaseAssert> getCaseAsserts() {
+ return Arrays.asList(
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_normal",
"abc123456", "***123456"),
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_short",
"ab", "**"),
+ new MaskAlgorithmExecuteCaseAssert("zero_from_x_empty",
"", ""));
+ }
+ }
}