Skip to content

Commit 1ec3c42

Browse files
committed
refactor: Resolve SonarCloud new-code issues
- Extract MINIMUM_KEYWORD/MAXIMUM_KEYWORD constants (S1192: each literal now appears 3 times across the integer and number checks). - Use an unnamed catch variable for the discarded parse exception. - Replace try/catch + fail() with assertDoesNotThrow() in the query test.
1 parent 1bbc2fe commit 1ec3c42

2 files changed

Lines changed: 32 additions & 24 deletions

File tree

src/main/java/com/retailsvc/http/validate/DefaultValidator.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
public final class DefaultValidator implements Validator {
4949

5050
private static final String FORMAT_KEYWORD = "format";
51+
private static final String MINIMUM_KEYWORD = "minimum";
52+
private static final String MAXIMUM_KEYWORD = "maximum";
5153
private static final Optional<ValidationError> OK = Optional.empty();
5254

5355
private record FormatCheck(Predicate<String> isValid, String message) {}
@@ -386,7 +388,7 @@ private static Optional<ValidationError> checkInteger(
386388
BigInteger n;
387389
try {
388390
n = new BigDecimal(num.toString()).toBigIntegerExact();
389-
} catch (ArithmeticException | NumberFormatException notIntegral) {
391+
} catch (ArithmeticException | NumberFormatException _) {
390392
return err(pointer, "type", "expected integer", value);
391393
}
392394
return checkIntegerBounds(n, s, pointer);
@@ -395,10 +397,10 @@ private static Optional<ValidationError> checkInteger(
395397
private static Optional<ValidationError> checkIntegerBounds(
396398
long n, IntegerSchema s, String pointer) {
397399
if (s.minimum() != null && n < s.minimum()) {
398-
return err(pointer, "minimum", "integer below minimum " + s.minimum(), n);
400+
return err(pointer, MINIMUM_KEYWORD, "integer below minimum " + s.minimum(), n);
399401
}
400402
if (s.maximum() != null && n > s.maximum()) {
401-
return err(pointer, "maximum", "integer above maximum " + s.maximum(), n);
403+
return err(pointer, MAXIMUM_KEYWORD, "integer above maximum " + s.maximum(), n);
402404
}
403405
if (s.exclusiveMinimum() != null && n <= s.exclusiveMinimum()) {
404406
return err(
@@ -424,10 +426,10 @@ private static Optional<ValidationError> checkIntegerBounds(
424426
// Magnitude exceeds signed-long range: it breaches whichever bound lies on its side, and no
425427
// int32/int64 format can represent it.
426428
if (n.signum() > 0 && (s.maximum() != null || s.exclusiveMaximum() != null)) {
427-
return err(pointer, "maximum", "integer out of range", n);
429+
return err(pointer, MAXIMUM_KEYWORD, "integer out of range", n);
428430
}
429431
if (n.signum() < 0 && (s.minimum() != null || s.exclusiveMinimum() != null)) {
430-
return err(pointer, "minimum", "integer out of range", n);
432+
return err(pointer, MINIMUM_KEYWORD, "integer out of range", n);
431433
}
432434
if (s.format() != null && INTEGER_FORMAT_CHECKS.containsKey(s.format())) {
433435
return err(pointer, FORMAT_KEYWORD, INTEGER_FORMAT_CHECKS.get(s.format()).message(), n);
@@ -443,10 +445,10 @@ private static Optional<ValidationError> checkNumber(
443445
double n = num.doubleValue();
444446

445447
if (s.minimum() != null && n < s.minimum().doubleValue()) {
446-
return err(pointer, "minimum", "number below minimum " + s.minimum(), n);
448+
return err(pointer, MINIMUM_KEYWORD, "number below minimum " + s.minimum(), n);
447449
}
448450
if (s.maximum() != null && n > s.maximum().doubleValue()) {
449-
return err(pointer, "maximum", "number above maximum " + s.maximum(), n);
451+
return err(pointer, MAXIMUM_KEYWORD, "number above maximum " + s.maximum(), n);
450452
}
451453
if (s.exclusiveMinimum() != null && n <= s.exclusiveMinimum().doubleValue()) {
452454
return err(pointer, "exclusiveMinimum", "number not greater than " + s.exclusiveMinimum(), n);

src/test/java/com/retailsvc/http/QueryParamSmugglingTest.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import static java.net.http.HttpRequest.BodyPublishers.noBody;
44
import static org.assertj.core.api.Assertions.assertThat;
5-
import static org.assertj.core.api.Assertions.fail;
5+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
66

77
import com.retailsvc.http.spec.Spec;
88
import java.io.InputStream;
@@ -32,21 +32,27 @@ void encodedAmpersandCannotSmuggleAValuePastQueryValidation() throws Exception {
3232

3333
@SuppressWarnings("unchecked")
3434
private void constrainQ1ToLowercaseLetters() {
35-
try (InputStream in = QueryParamSmugglingTest.class.getResourceAsStream("/openapi.json")) {
36-
Map<String, Object> raw =
37-
(Map<String, Object>)
38-
gson.fromJson(new String(in.readAllBytes(), StandardCharsets.UTF_8), Map.class);
39-
var paths = (Map<String, Object>) raw.get("paths");
40-
var op = (Map<String, Object>) ((Map<String, Object>) paths.get("/params/query")).get("get");
41-
for (Object p : (List<Object>) op.get("parameters")) {
42-
var param = (Map<String, Object>) p;
43-
if ("q1".equals(param.get("name"))) {
44-
((Map<String, Object>) param.get("schema")).put("pattern", "^[a-z]+$");
45-
}
46-
}
47-
spec = Spec.from(raw);
48-
} catch (Exception e) {
49-
fail(e);
50-
}
35+
spec =
36+
assertDoesNotThrow(
37+
() -> {
38+
try (InputStream in =
39+
QueryParamSmugglingTest.class.getResourceAsStream("/openapi.json")) {
40+
Map<String, Object> raw =
41+
(Map<String, Object>)
42+
gson.fromJson(
43+
new String(in.readAllBytes(), StandardCharsets.UTF_8), Map.class);
44+
var paths = (Map<String, Object>) raw.get("paths");
45+
var op =
46+
(Map<String, Object>)
47+
((Map<String, Object>) paths.get("/params/query")).get("get");
48+
for (Object p : (List<Object>) op.get("parameters")) {
49+
var param = (Map<String, Object>) p;
50+
if ("q1".equals(param.get("name"))) {
51+
((Map<String, Object>) param.get("schema")).put("pattern", "^[a-z]+$");
52+
}
53+
}
54+
return Spec.from(raw);
55+
}
56+
});
5157
}
5258
}

0 commit comments

Comments
 (0)