Skip to content

Commit

Permalink
MONDRIAN: integrate change #14842 from pacino: [MONDRIAN-1057] Fixes …
Browse files Browse the repository at this point in the history
…a problem with the regular expression support in MySQL and Oracle dialects. They were only removing a single pair of \Q and \R markers and would not remove the others, if any.

[git-p4: depot-paths = "//open/mondrian/": change = 14850]
  • Loading branch information
Will Gorman committed Dec 23, 2011
1 parent d0d97d6 commit b31087d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 14 deletions.
12 changes: 5 additions & 7 deletions src/main/mondrian/spi/impl/MySqlDialect.java
Expand Up @@ -26,7 +26,7 @@ public class MySqlDialect extends JdbcDialectImpl {

private final String flagsRegexp = "^(\\(\\?([a-zA-Z])\\)).*$";
private final Pattern flagsPattern = Pattern.compile(flagsRegexp);
private final String escapeRegexp = "^.*(\\\\Q(.*)\\\\E).*$";
private final String escapeRegexp = "(\\\\Q([^\\\\Q]+)\\\\E)";
private final Pattern escapePattern = Pattern.compile(escapeRegexp);

public static final JdbcDialectFactory FACTORY =
Expand Down Expand Up @@ -285,13 +285,11 @@ public String generateRegularExpression(
+ javaRegex.substring(flagsMatcher.end(1));
}
final Matcher escapeMatcher = escapePattern.matcher(javaRegex);
if (escapeMatcher.matches()) {
String sequence = escapeMatcher.group(2);
sequence = sequence.replaceAll("\\\\", "\\\\");
while (escapeMatcher.find()) {
javaRegex =
javaRegex.substring(0, escapeMatcher.start(1))
+ sequence.toUpperCase()
+ javaRegex.substring(escapeMatcher.end(1));
javaRegex.replace(
escapeMatcher.group(1),
escapeMatcher.group(2));
}
final StringBuilder sb = new StringBuilder();
sb.append("UPPER(");
Expand Down
10 changes: 3 additions & 7 deletions src/main/mondrian/spi/impl/OracleDialect.java
Expand Up @@ -23,7 +23,7 @@ public class OracleDialect extends JdbcDialectImpl {

private final String flagsRegexp = "^(\\(\\?([a-zA-Z])\\)).*$";
private final Pattern flagsPattern = Pattern.compile(flagsRegexp);
private final String escapeRegexp = "^.*(\\\\Q(.*)\\\\E).*$";
private final String escapeRegexp = "(\\\\Q([^\\\\Q]+)\\\\E)";
private final Pattern escapePattern = Pattern.compile(escapeRegexp);

public static final JdbcDialectFactory FACTORY =
Expand Down Expand Up @@ -112,15 +112,11 @@ public String generateRegularExpression(
suffix = "";
}
final Matcher escapeMatcher = escapePattern.matcher(javaRegex);
if (escapeMatcher.matches()) {
// We need to convert escape characters \E and \Q into
// oracle compatible escapes.
String sequence = escapeMatcher.group(2);
sequence = sequence.replaceAll("\\\\", "\\\\");
while (escapeMatcher.find()) {
javaRegex =
javaRegex.replace(
escapeMatcher.group(1),
sequence);
escapeMatcher.group(2));
}
final StringBuilder sb = new StringBuilder();
sb.append("REGEXP_LIKE(");
Expand Down
44 changes: 44 additions & 0 deletions testsrc/main/mondrian/test/DialectTest.java
Expand Up @@ -943,6 +943,50 @@ public void testAllowsRegularExpressionInWhereClause() throws Exception {
}
}

/**
* This is a test for
* <a href="http://jira.pentaho.com/browse/MONDRIAN-1057">
* http://jira.pentaho.com/browse/MONDRIAN-1057</a>
* Some dialects are not removing the \Q and \E markers if they
* are in the middle of the regexp.
*/
public void testComplexRegularExpression() throws Exception {
final String regexp =
"(?i).*\\QJeanne\\E.*|.*\\QSheri\\E.*|.*\\QJonathan\\E.*|.*\\QJewel\\E.*";
Dialect dialect = getDialect();
if (dialect.allowsRegularExpressionInWhereClause()) {
assertNotNull(
dialect.generateRegularExpression(
dialect.quoteIdentifier("customer", "fname"),
regexp));
StringBuilder sb =
new StringBuilder(
"select "
+ dialect.quoteIdentifier("customer", "fname")
+ " from "
+ dialect.quoteIdentifier("customer")
+ " group by "
+ dialect.quoteIdentifier("customer", "fname")
+ " having "
+ dialect.generateRegularExpression(
dialect.quoteIdentifier("customer", "fname"),
regexp));
final ResultSet resultSet =
getConnection().createStatement().executeQuery(sb.toString());
int i = 0;
while (resultSet.next()) {
i++;
}
assertEquals(7, i);
resultSet.close();
} else {
assertNull(
dialect.generateRegularExpression(
"Foo",
"(?i).*\\QBar\\E.*"));
}
}

public void testRegularExpressionSqlInjection() throws SQLException {
// bug mondrian-983
// We know that mysql's dialect can handle this regex
Expand Down

0 comments on commit b31087d

Please sign in to comment.