1616
1717import com .google .errorprone .annotations .CanIgnoreReturnValue ;
1818import com .google .errorprone .annotations .CheckReturnValue ;
19+ import com .google .re2j .Pattern ;
1920import dev .cel .common .CelErrorCode ;
2021import dev .cel .common .CelRuntimeException ;
2122import dev .cel .common .annotations .Internal ;
3132 */
3233@ Internal
3334public class InterpreterException extends Exception {
35+ // Allow format specifiers of %d, %f, %s and %n only.
36+ private static final Pattern ALLOWED_FORMAT_SPECIFIERS = Pattern .compile ("%[^dfsn]" );
3437 private final CelErrorCode errorCode ;
3538
3639 public CelErrorCode getErrorCode () {
@@ -47,7 +50,7 @@ public static class Builder {
4750
4851 @ SuppressWarnings ({"AnnotateFormatMethod" }) // Format strings are optional.
4952 public Builder (String message , Object ... args ) {
50- this .message = args . length > 0 ? String . format (message , args ) : message ;
53+ this .message = safeFormat (message , args );
5154 }
5255
5356 @ SuppressWarnings ({"AnnotateFormatMethod" }) // Format strings are optional.
@@ -64,7 +67,7 @@ public Builder(RuntimeException e, String message, Object... args) {
6467 this .cause = e ;
6568 }
6669
67- this .message = args . length > 0 ? String . format (message , args ) : message ;
70+ this .message = safeFormat (message , args );
6871 }
6972
7073 @ CanIgnoreReturnValue
@@ -97,6 +100,15 @@ public InterpreterException build() {
97100 cause ,
98101 errorCode );
99102 }
103+
104+ private static String safeFormat (String message , Object [] args ) {
105+ if (args .length == 0 ) {
106+ return message ;
107+ }
108+
109+ String sanitizedMessage = ALLOWED_FORMAT_SPECIFIERS .matcher (message ).replaceAll ("" );
110+ return String .format (sanitizedMessage , args );
111+ }
100112 }
101113
102114 private InterpreterException (String message , Throwable cause , CelErrorCode errorCode ) {
0 commit comments