From 24ed6de6aaece130fa38e758712cedf6987212d0 Mon Sep 17 00:00:00 2001 From: Chris Harding Date: Mon, 6 Aug 2018 20:49:01 +0100 Subject: [PATCH] Add backslash escape support to containsSqlScriptDelimiters Prior to this commit, ScriptUtils supported MySQL-style escapes ('\\') when splitting a script into statements; however, MySQL-style escapes were not supported when determining if a given script contained a specified statement delimiter. This caused executeSqlScript() to erroneously fallback to a newline as the statement separator in such cases. This commit fixes this issue by implementing the same check for MySQL-style escapes in containsSqlScriptDelimiters() that was already present in splitSqlScript(). Issue: SPR-17120 --- .../jdbc/datasource/init/ScriptUtils.java | 14 +++++++++++++- .../jdbc/datasource/init/ScriptUtilsUnitTests.java | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java index 5f5ec89113..15a7af602f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java @@ -343,8 +343,20 @@ public abstract class ScriptUtils { */ public static boolean containsSqlScriptDelimiters(String script, String delim) { boolean inLiteral = false; + boolean inEscape = false; for (int i = 0; i < script.length(); i++) { - if (script.charAt(i) == '\'') { + + char c = script.charAt(i); + if (c == '\\') { + inEscape = !inEscape; + continue; + } + else if (inEscape) { + inEscape = false; + continue; + } + + if (c == '\'') { inLiteral = !inLiteral; } if (!inLiteral && script.startsWith(delim, i)) { diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java index 3cb03b129f..82df2fd770 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java @@ -170,6 +170,8 @@ public class ScriptUtilsUnitTests { assertTrue(containsSqlScriptDelimiters("select 1\n select 2", "\n")); assertFalse(containsSqlScriptDelimiters("select 1\n select 2", "\n\n")); assertTrue(containsSqlScriptDelimiters("select 1\n\n select 2", "\n\n")); + assertTrue(containsSqlScriptDelimiters("insert into users(first_name, last_name)\nvalues('Charles', 'd\\'Artagnan');", ";")); + assertFalse(containsSqlScriptDelimiters("insert into users(first_name, last_name)\nvalues('a\\\\', 'b;')", ";")); } private String readScript(String path) throws Exception {