From bb109139e859cf92034fbbd6408636ac3782cbad Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 25 Jan 2016 20:54:59 -0600 Subject: [PATCH] HHH-10446 - Comment delimiters not "escaped" within (VAR)CHAR literals within native queries --- .../engine/query/spi/ParameterParser.java | 42 ++++++++++--------- .../engine/query/ParameterParserTest.java | 25 +++++++++-- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java index e392cdea07..1cb9f75478 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java @@ -94,7 +94,20 @@ public class ParameterParser { final char c = sqlString.charAt( indx ); final boolean lastCharacter = indx == stringLength-1; - if ( inDelimitedComment ) { + // if we are "in" a certain context, check first for the end of that context + if ( inSingleQuotes ) { + recognizer.other( c ); + if ( '\'' == c ) { + inSingleQuotes = false; + } + } + else if ( inDoubleQuotes ) { + recognizer.other( c ); + if ( '\"' == c ) { + inDoubleQuotes = false; + } + } + else if ( inDelimitedComment ) { recognizer.other( c ); if ( !lastCharacter && '*' == c && '/' == sqlString.charAt( indx+1 ) ) { inDelimitedComment = false; @@ -102,12 +115,6 @@ public class ParameterParser { indx++; } } - else if ( !lastCharacter && '/' == c && '*' == sqlString.charAt( indx+1 ) ) { - inDelimitedComment = true; - recognizer.other( c ); - recognizer.other( sqlString.charAt( indx+1 ) ); - indx++; - } else if ( inLineComment ) { recognizer.other( c ); // see if the character ends the line @@ -122,6 +129,13 @@ public class ParameterParser { } } } + // otherwise, see if we start such a context + else if ( !lastCharacter && '/' == c && '*' == sqlString.charAt( indx+1 ) ) { + inDelimitedComment = true; + recognizer.other( c ); + recognizer.other( sqlString.charAt( indx+1 ) ); + indx++; + } else if ( '-' == c ) { recognizer.other( c ); if ( !lastCharacter && '-' == sqlString.charAt( indx+1 ) ) { @@ -130,30 +144,20 @@ public class ParameterParser { indx++; } } - else if ( inDoubleQuotes ) { - if ( '\"' == c ) { - inDoubleQuotes = false; - } - recognizer.other( c ); - } else if ( '\"' == c ) { inDoubleQuotes = true; recognizer.other( c ); } - else if ( inSingleQuotes ) { - if ( '\'' == c ) { - inSingleQuotes = false; - } - recognizer.other( c ); - } else if ( '\'' == c ) { inSingleQuotes = true; recognizer.other( c ); } + // special handling for backslash else if ( '\\' == c ) { // skip sending the backslash and instead send then next character, treating is as a literal recognizer.other( sqlString.charAt( ++indx ) ); } + // otherwise else { if ( c == ':' ) { // named parameter diff --git a/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java b/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java index abe02e7193..33928f4a00 100644 --- a/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java +++ b/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java @@ -6,12 +6,13 @@ */ package org.hibernate.engine.query; -import org.junit.Test; - import org.hibernate.engine.query.spi.ParamLocationRecognizer; import org.hibernate.engine.query.spi.ParameterParser; -import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -48,6 +49,24 @@ public class ParameterParserTest extends BaseUnitTestCase { assertTrue(recognizer.getNamedParameterDescriptionMap().containsKey("param")); } + @Test + public void testDoubleDashInCharLiteral() { + ParamLocationRecognizer recognizer = new ParamLocationRecognizer(); + + ParameterParser.parse("select coalesce(i.name, '--NONE--') as itname from Item i where i.intVal=? ",recognizer); + + assertEquals( 1, recognizer.getOrdinalParameterLocationList().size() ); + } + + @Test + public void testSlashStarInCharLiteral() { + ParamLocationRecognizer recognizer = new ParamLocationRecognizer(); + + ParameterParser.parse("select coalesce(i.name, '/*NONE') as itname from Item i where i.intVal=? ",recognizer); + + assertEquals( 1, recognizer.getOrdinalParameterLocationList().size() ); + } + @Test public void testApostropheInOracleAlias() { ParamLocationRecognizer recognizer = new ParamLocationRecognizer();