Skip to content

Commit e520779

Browse files
timtebeekclaude
andcommitted
Fix IndexOutOfBoundsException with quoted parameters in JulParameterizedArguments
Escape special characters (backslashes and double quotes) in the format string before passing it to JavaTemplate. Without escaping, format strings containing quotes like "Log message \"{0}\"" resulted in invalid Java syntax during template application. Fixes #273 Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 011170e commit e520779

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/main/java/org/openrewrite/java/logging/slf4j/JulParameterizedArguments.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ public static boolean isStringLiteral(Expression expression) {
6565
return expression instanceof J.Literal && TypeUtils.isString(((J.Literal) expression).getType());
6666
}
6767

68+
/**
69+
* Escapes special characters in a string so it can be safely used as content
70+
* inside a Java string literal in a JavaTemplate.
71+
*/
72+
private static String escapeForJavaStringLiteral(String s) {
73+
// Order matters: escape backslashes first to avoid double-escaping
74+
return s.replace("\\", "\\\\").replace("\"", "\\\"");
75+
}
76+
6877
private static @Nullable String getMethodIdentifier(Expression levelArgument) {
6978
String levelSimpleName = levelArgument instanceof J.FieldAccess ?
7079
(((J.FieldAccess) levelArgument).getName().getSimpleName()) :
@@ -124,12 +133,13 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
124133
.withType(((JavaType.Array) requireNonNull(newArray.getType())).withElemType(JavaType.ShallowClass.build("java.lang.Object")));
125134
}
126135

136+
String slf4jFormatString = escapeForJavaStringLiteral(originalFormatString.replaceAll("\\{\\d*}", "{}"));
127137
J.MethodInvocation updatedMi = JavaTemplate.builder(newName + "(\"#{}\",#{anyArray(Object)})")
128138
.build()
129139
.apply(
130140
getCursor(),
131141
method.getCoordinates().replaceMethod(),
132-
originalFormatString.replaceAll("\\{\\d*}", "{}"),
142+
slf4jFormatString,
133143
updatedStringFormatArgument
134144
);
135145

src/test/java/org/openrewrite/java/logging/slf4j/JulParameterizedArgumentsTest.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.openrewrite.java.logging.slf4j;
1717

1818
import org.junit.jupiter.api.Disabled;
19+
import org.junit.jupiter.api.Nested;
1920
import org.junit.jupiter.api.Test;
2021
import org.openrewrite.DocumentExample;
2122
import org.openrewrite.Issue;
@@ -295,4 +296,65 @@ void method(Logger logger, Level level, String param1) {
295296
)
296297
);
297298
}
299+
300+
@Nested
301+
@Issue("https://github.com/openrewrite/rewrite-logging-frameworks/issues/273")
302+
class EscapedCharactersInFormatString {
303+
304+
@Test
305+
void quotedParameters() {
306+
rewriteRun(
307+
// language=java
308+
java(
309+
"""
310+
import java.util.logging.Level;
311+
import java.util.logging.Logger;
312+
313+
class Test {
314+
void method(Logger logger, String param1) {
315+
logger.log(Level.SEVERE, "Log message with quoted parameter \\"{0}\\"", param1);
316+
}
317+
}
318+
""",
319+
"""
320+
import org.slf4j.Logger;
321+
322+
class Test {
323+
void method(Logger logger, String param1) {
324+
logger.error("Log message with quoted parameter \\"{}\\"", param1);
325+
}
326+
}
327+
"""
328+
)
329+
);
330+
}
331+
332+
@Test
333+
void backslashInFormatString() {
334+
rewriteRun(
335+
// language=java
336+
java(
337+
"""
338+
import java.util.logging.Level;
339+
import java.util.logging.Logger;
340+
341+
class Test {
342+
void method(Logger logger, String param1) {
343+
logger.log(Level.INFO, "Path: C:\\\\Users\\\\{0}", param1);
344+
}
345+
}
346+
""",
347+
"""
348+
import org.slf4j.Logger;
349+
350+
class Test {
351+
void method(Logger logger, String param1) {
352+
logger.info("Path: C:\\\\Users\\\\{}", param1);
353+
}
354+
}
355+
"""
356+
)
357+
);
358+
}
359+
}
298360
}

0 commit comments

Comments
 (0)