This is an automated email from the ASF dual-hosted git repository.

zabetak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git

commit 7139d42e8d8c75ff0700274b81f4ddf3e90b905c
Author: mdayakar <mdaya...@cloudera.com>
AuthorDate: Mon Jul 10 18:26:05 2023 +0530

    HIVE-27488: Incorrect escaping of quotes in HPL/SQL literals (Dayakar M 
reviewed by Attila Turoczy, Stamatis Zampetakis)
    
    Closes #4476
---
 .../main/java/org/apache/hive/hplsql/Utils.java    | 12 +++++---
 .../java/org/apache/hive/hplsql/TestUtils.java     | 35 ++++++++++++++++++++++
 hplsql/src/test/queries/local/dbms_output.sql      |  6 ++++
 hplsql/src/test/results/local/dbms_output.out.txt  |  6 ++++
 4 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/hplsql/src/main/java/org/apache/hive/hplsql/Utils.java 
b/hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
index 2a86f55a3e9..c7d0f202f11 100644
--- a/hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
+++ b/hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
@@ -32,18 +32,22 @@ public class Utils {
          }
          
          int len = s.length();
-         StringBuilder s2 = new StringBuilder(len);      
+         StringBuilder s2 = new StringBuilder(len);
+         boolean isEscape = true;
          
          for (int i = 0; i < len; i++) {
                char ch = s.charAt(i);
                char ch2 = (i < len - 1) ? s.charAt(i+1) : 0;
                  
-           if((i == 0 || i == len -1) && (ch == '\'' || ch == '"'))
+           if((i == 0 || i == len - 1) && (ch == '\'' || ch == '"'))
              continue;
            else
-           // \' and '' escape sequences
-           if((ch == '\\' && ch2 == '\'') || (ch == '\'' && ch2 == '\''))
+           // \' and '' escape sequences and include ' if last two characters 
are ''
+           if((ch == '\\' && ch2 == '\'') || (ch == '\'' && ch2 == '\'' && 
isEscape && i != len - 2)) {
+             isEscape = false;
              continue;
+           }
+           isEscape = true;
            
            s2.append(ch);      
          }
diff --git a/hplsql/src/test/java/org/apache/hive/hplsql/TestUtils.java 
b/hplsql/src/test/java/org/apache/hive/hplsql/TestUtils.java
new file mode 100644
index 00000000000..1060f6a5e66
--- /dev/null
+++ b/hplsql/src/test/java/org/apache/hive/hplsql/TestUtils.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hive.hplsql;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestUtils {
+
+  @Test
+  public void testUnquoteStringRemovesOneQuoteWhenTwoConsecutive() {
+    Assert.assertEquals("a'a", Utils.unquoteString("'a''a'"));
+    Assert.assertEquals("'a", Utils.unquoteString("'''a'"));
+    Assert.assertEquals("a'", Utils.unquoteString("'a'''"));
+    Assert.assertEquals("''aa", Utils.unquoteString("'''''aa'"));
+    Assert.assertEquals("a''a", Utils.unquoteString("'a''''a'"));
+    Assert.assertEquals("aa''", Utils.unquoteString("'aa'''''"));
+  }
+}
diff --git a/hplsql/src/test/queries/local/dbms_output.sql 
b/hplsql/src/test/queries/local/dbms_output.sql
index 37d73133ca9..d8855b4336f 100644
--- a/hplsql/src/test/queries/local/dbms_output.sql
+++ b/hplsql/src/test/queries/local/dbms_output.sql
@@ -3,4 +3,10 @@ DECLARE
 BEGIN
   DBMS_OUTPUT.PUT_LINE('Hello, world!');
   DBMS_OUTPUT.PUT_LINE(str);
+  DBMS_OUTPUT.PUT_LINE('a''a');
+  DBMS_OUTPUT.PUT_LINE('''a');
+  DBMS_OUTPUT.PUT_LINE('a''');
+  DBMS_OUTPUT.PUT_LINE('''''aa');
+  DBMS_OUTPUT.PUT_LINE('a''''a');
+  DBMS_OUTPUT.PUT_LINE('aa''''');
 END;
diff --git a/hplsql/src/test/results/local/dbms_output.out.txt 
b/hplsql/src/test/results/local/dbms_output.out.txt
index b6ed0e0eb7f..d68f919a93e 100644
--- a/hplsql/src/test/results/local/dbms_output.out.txt
+++ b/hplsql/src/test/results/local/dbms_output.out.txt
@@ -1,3 +1,9 @@
 Ln:2 DECLARE str VARCHAR = 'Hello, world!'
 Hello, world!
 Hello, world!
+a'a
+'a
+a'
+''aa
+a''a
+aa''

Reply via email to