Skip to content

Commit 8643b6d

Browse files
committed
#921 Do not parse escapes within double quotes
1 parent d6f4fdb commit 8643b6d

3 files changed

Lines changed: 36 additions & 16 deletions

File tree

src/docs/asciidoc/release_notes.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ This results in two minor breaking changes:
4848
+
4949
** Reserved words are no longer considered simple identifiers by `enquoteIdentifier` and `isSimpleIdentifier` and will be quoted (or -- for dialect 1 -- result in a `SQLFeatureNotSupportedException`)
5050
** Presence of the NUL character (U+0000) in an identifier passed to `enquoteIdentifier` will result in a `SQLSyntaxErrorException`
51+
* Fixed: JDBC escapes should not be parsed inside dialect 3 delimited identifiers or dialect 1 string literals (https://github.com/FirebirdSQL/jaybird/issues/921[#921])
5152

5253
=== Jaybird 6.0.4
5354

src/main/org/firebirdsql/jdbc/escape/FBEscapedParser.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public static String parse(final String sql) throws SQLException {
116116
case INITIAL_STATE -> {
117117
// Ignore leading whitespace
118118
}
119-
case NORMAL_STATE, LITERAL_STATE,
119+
case NORMAL_STATE, LITERAL_STATE, DELIMITED_IDENTIFIER,
120120
START_LINE_COMMENT, LINE_COMMENT, START_BLOCK_COMMENT, BLOCK_COMMENT, END_BLOCK_COMMENT,
121121
POSSIBLE_Q_LITERAL_ENTER -> buffer.append(currentChar);
122122
case ESCAPE_ENTER_STATE -> {
@@ -375,6 +375,7 @@ protected ParserState nextState(char inputChar) throws FBSQLParseException {
375375
protected ParserState nextState(char inputChar) {
376376
return switch (inputChar) {
377377
case '\'' -> LITERAL_STATE;
378+
case '"' -> DELIMITED_IDENTIFIER;
378379
case '{' -> ESCAPE_ENTER_STATE;
379380
case '}' -> ESCAPE_EXIT_STATE;
380381
case '-' -> START_LINE_COMMENT;
@@ -393,6 +394,15 @@ protected ParserState nextState(char inputChar) {
393394
return (inputChar == '\'') ? NORMAL_STATE : LITERAL_STATE;
394395
}
395396
},
397+
/**
398+
* Dialect 3 delimited identifier or dialect 1 literal text (text inside double quotes).
399+
*/
400+
DELIMITED_IDENTIFIER {
401+
@Override
402+
protected ParserState nextState(char inputChar) {
403+
return (inputChar == '"') ? NORMAL_STATE : DELIMITED_IDENTIFIER;
404+
}
405+
},
396406
/**
397407
* Start of JDBC escape ({ character encountered).
398408
*/

src/test/org/firebirdsql/jdbc/escape/FBEscapedParserTest.java

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -361,22 +361,31 @@ void testQLiteral_InLiteralEndOfString_throwsParseException() {
361361
"Unexpected end of string at parser state Q_LITERAL_START");
362362
}
363363

364-
@Test
365-
void testQLiteralSpecials() throws Exception {
366-
checkQLiteralSpecialsBalancedStartEnd('(', ')');
367-
checkQLiteralSpecialsBalancedStartEnd(')', ')');
368-
checkQLiteralSpecialsBalancedStartEnd('{', '}');
369-
checkQLiteralSpecialsBalancedStartEnd('}', '}');
370-
checkQLiteralSpecialsBalancedStartEnd('[', ']');
371-
checkQLiteralSpecialsBalancedStartEnd(']', ']');
372-
checkQLiteralSpecialsBalancedStartEnd('<', '>');
373-
checkQLiteralSpecialsBalancedStartEnd('>', '>');
374-
}
375-
376-
private void checkQLiteralSpecialsBalancedStartEnd(char start, char end) throws Exception {
364+
@ParameterizedTest
365+
@CsvSource(useHeadersInDisplayName = true, textBlock = """
366+
start, end
367+
(, )
368+
), )
369+
{, }
370+
[, ]
371+
], ]
372+
<, >
373+
>, >
374+
""")
375+
void checkQLiteralSpecialsBalancedStartEnd(char start, char end) throws Exception {
377376
final String input = "q'" + start + " {fn EXP(2)} " + end + "'";
378377

379-
String parseResult = FBEscapedParser.toNativeSql(input);
380-
assertEquals(input, parseResult, "Unexpected output");
378+
assertEquals(input, FBEscapedParser.toNativeSql(input), "Unexpected output");
379+
}
380+
381+
@ParameterizedTest
382+
@ValueSource(strings = {
383+
"'{fn EXP(2)}'",
384+
"q'{{fn EXP(2)}}'",
385+
"\"{fn EXP(2)}\""
386+
})
387+
void escapesInLiteralsOrDelimitedIdentifiers_notAnEscape(String input) throws Exception {
388+
assertEquals(input, FBEscapedParser.toNativeSql(input), "Unexpected output");
381389
}
390+
382391
}

0 commit comments

Comments
 (0)