Bug #84324 CallableStatement.extractProcedureName() not work when catalog name with dash-
Submitted: 23 Dec 2016 10:59 Modified: 20 Apr 2017 20:21
Reporter: Hongjie ZHANG (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:5.1.40 OS:Any
Assigned to: Filipe Silva CPU Architecture:Any
Tags: 5.1.40, CallableStatement, Dash, extractProcedureName, mysql-connector-java

[23 Dec 2016 10:59] Hongjie ZHANG
Description:
CallableStatement.extractProcedureName() don't work correct when procedure name with dash "-"

How to repeat:
import com.mysql.jdbc.StringUtils;
import com.mysql.jdbc.util.BaseBugReport;

public class MyBugReport extends BaseBugReport{

	@Override
	public void setUp() throws Exception {}

	@Override
	public void tearDown() throws Exception {}

	@Override
	public void runTest() throws Exception {
		String originalSql= "CALL a-bug.proc_stock(?,?)";
		
		//mysql-connector-java 5.1.40
		//com.mysql.jdbc.CallableStatement.extractProcedureName()
		String sanitizedSql = StringUtils.stripComments(originalSql, "`\"'", "`\"'", true, false, true, true);
		
		assertTrue("\""+sanitizedSql+"\"  should be equal to \""+originalSql+"\"", originalSql.equals(sanitizedSql));
	}

	public static void main(String[] args) throws Exception {
	      new MyBugReport().run();
	}

}

Suggested fix:
package com.mysql.jdbc;

public class StringUtils {

    public static String stripComments(String src, String stringOpens, String stringCloses, boolean slashStarComments, boolean slashSlashComments,
            boolean hashComments, boolean dashDashComments) {
        if (src == null) {
            return null;
        }

        StringBuilder strBuilder = new StringBuilder(src.length());

        // It's just more natural to deal with this as a stream when parsing..This code is currently only called when parsing the kind of metadata that
        // developers are strongly recommended to cache anyways, so we're not worried about the _1_ extra object allocation if it cleans up the code

        StringReader sourceReader = new StringReader(src);

        int contextMarker = Character.MIN_VALUE;
        boolean escaped = false;
        int markerTypeFound = -1;

        int ind = 0;

        int currentChar = 0;

        try {
            while ((currentChar = sourceReader.read()) != -1) {

                if (markerTypeFound != -1 && currentChar == stringCloses.charAt(markerTypeFound) && !escaped) {
                    contextMarker = Character.MIN_VALUE;
                    markerTypeFound = -1;
                } else if ((ind = stringOpens.indexOf(currentChar)) != -1 && !escaped && contextMarker == Character.MIN_VALUE) {
                    markerTypeFound = ind;
                    contextMarker = currentChar;
                }

                if (contextMarker == Character.MIN_VALUE && currentChar == '/' && (slashSlashComments || slashStarComments)) {
                    currentChar = sourceReader.read();
                    if (currentChar == '*' && slashStarComments) {
                        int prevChar = 0;
                        while ((currentChar = sourceReader.read()) != '/' || prevChar != '*') {
                            if (currentChar == '\r') {

                                currentChar = sourceReader.read();
                                if (currentChar == '\n') {
                                    currentChar = sourceReader.read();
                                }
                            } else {
                                if (currentChar == '\n') {

                                    currentChar = sourceReader.read();
                                }
                            }
                            if (currentChar < 0) {
                                break;
                            }
                            prevChar = currentChar;
                        }
                        continue;
                    } else if (currentChar == '/' && slashSlashComments) {
                        while ((currentChar = sourceReader.read()) != '\n' && currentChar != '\r' && currentChar >= 0) {
                        }
                    }
                } else if (contextMarker == Character.MIN_VALUE && currentChar == '#' && hashComments) {
                    // Slurp up everything until the newline
                    while ((currentChar = sourceReader.read()) != '\n' && currentChar != '\r' && currentChar >= 0) {
                    }
                } else if (contextMarker == Character.MIN_VALUE && currentChar == '-' && dashDashComments) {
                    currentChar = sourceReader.read();

                    if (currentChar == -1 || currentChar != '-') {
                        strBuilder.append('-');

                        if (currentChar != -1) {
                            strBuilder.append((char) currentChar);
                        }

                        continue;
                    }

                    // Slurp up everything until the newline

                    while ((currentChar = sourceReader.read()) != '\n' && currentChar != '\r' && currentChar >= 0) {
                    }
                }

                if (currentChar != -1) {
                    strBuilder.append((char) currentChar);
                }
            }
        } catch (IOException ioEx) {
            // we'll never see this from a StringReader
        }

        return strBuilder.toString();
    }

}
[23 Dec 2016 11:02] Hongjie ZHANG
class MyBugReport extends BaseBugReport

Attachment: MyBugReport.java (application/octet-stream, text), 824 bytes.

[26 Dec 2016 12:18] Chiranjeevi Battula
Hello Hongjie ZHANG,

Thank you for the bug report and test case.
Verified this behavior on MySQL Connector / J 5.1.40.

Thanks,
Chiranjeevi.
[20 Apr 2017 20:21] Daniel So
Posted by developer:
 
Added the following entry to the Connector/J 5.1.42 changelog:

"CallableStatement.extractProcedureName() did not return the correct result when the procedure name contained a dash. This was due to an error in the isNullOrEmpty() method of the StringUtils.is class, which has now been corrected."
[21 Apr 2017 16:17] Daniel So
Posted by developer:
 
Corrected the changelog entry to the following: 

"CallableStatement.extractProcedureName() did not return the correct result when the procedure name contained a dash. This was due to an error in the stripComments() method of the StringUtils class, which has now been corrected. "