java:S1075 Hardcoded URIs rule bypassed by compile-time string concatenation

Product: SonarQube Community Build 26.5.0.122743
sonar-java version: sonar-java 8.29 (build 43460)
sonar-java SE version: sonar-java-symbolic-execution 8.16.4 (build 1912)
Java source level: 21 (javac 21, source/target 21)

Rule

java:S1075 — URIs should not be hardcoded

Description

S1075 fails to flag hardcoded URI/path string constants when they are expressed as a compile-time concatenation of string literals (e.g. "/group" + "/list.html"), even though the Java Language Specification mandates that such an expression is a constant expression folded to the single string "/group/list.html". The resulting constant is semantically identical to the single-literal form, which the rule does flag. This is an inconsistency: trivially splitting a literal with + silently suppresses the finding, giving an easy and unintended way to bypass the rule.

Reproducer

public class PathHolder {
​
    // BEFORE — S1075 is raised on both constants (expected)
    private static final String FILE_PATH_A    = "/home/user/documents/file.txt";
    private static final String URL_SUB_PATH_A = "/group/list.html";
​
    // AFTER — same compile-time values, but S1075 is NOT raised
    private static final String FILE_PATH_B    = "/home/user" + "/documents" + "/file.txt";
    private static final String URL_SUB_PATH_B = "/group" + "/list.html";
}

Both FILE_PATH_A and FILE_PATH_B compile to the exact same interned string constant "/home/user/documents/file.txt"; likewise for URL_SUB_PATH_A/URL_SUB_PATH_B. Yet SonarJava reports S1075 only on the _A variants.

Expected behavior

S1075 should flag hardcoded URI/path constants regardless of whether the string is written as a single literal or as a concatenation of string literals, since JLS constant folding makes the two forms equivalent.

Actual behavior

S1075 is raised on the single-literal form but disappears when the same literal is split with + into a constant concatenation expression, allowing the rule to be trivially bypassed.

Hello @Chordrain,

Thank you for reporting this false negative.
You are right, it seems like the rule should raise an issue in these examples, as they are essentially equivalent to constant strings. I have created a ticket for us to address this.

Best regards,
Aurélien