org.mariadb.jdbc.util.Security Maven / Gradle / Ivy
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab
package org.mariadb.jdbc.util;
public final class Security {
/**
* Parse the option "sessionVariable" to ensure having no injection. semi-column not in string
* will be replaced by comma.
*
* @param sessionVariable option value
* @return parsed String
*/
public static String parseSessionVariables(String sessionVariable) {
StringBuilder out = new StringBuilder();
StringBuilder sb = new StringBuilder();
Parse state = Parse.Normal;
boolean iskey = true;
boolean singleQuotes = true;
boolean first = true;
String key = null;
char[] chars = sessionVariable.toCharArray();
for (char car : chars) {
if (state == Parse.Escape) {
sb.append(car);
state = Parse.String;
continue;
}
switch (car) {
case '"':
if (state == Parse.Normal) {
state = Parse.String;
singleQuotes = false;
} else if (!singleQuotes) {
state = Parse.Normal;
}
break;
case '\'':
if (state == Parse.Normal) {
state = Parse.String;
singleQuotes = true;
} else if (singleQuotes) {
state = Parse.Normal;
}
break;
case '\\':
if (state == Parse.String) {
state = Parse.Escape;
}
break;
case ';':
case ',':
if (state == Parse.Normal) {
if (!iskey) {
if (!first) {
out.append(",");
}
out.append(key);
out.append(sb);
first = false;
} else {
key = sb.toString().trim();
if (!key.isEmpty()) {
if (!first) {
out.append(",");
}
out.append(key);
first = false;
}
}
iskey = true;
key = null;
sb = new StringBuilder();
continue;
}
break;
case '=':
if (state == Parse.Normal && iskey) {
key = sb.toString().trim();
iskey = false;
sb = new StringBuilder();
}
break;
default:
// nothing
}
sb.append(car);
}
if (!iskey) {
if (!first) {
out.append(",");
}
out.append(key);
out.append(sb);
} else {
String tmpkey = sb.toString().trim();
if (!tmpkey.isEmpty() && !first) {
out.append(",");
}
out.append(tmpkey);
}
return out.toString();
}
private enum Parse {
Normal,
String, /* inside string */
Escape /* found backslash */
}
}