fix(chat2db): ensure proper escaping of string values in SQL queries

String values in SQL queries are now properly escaped to prevent potential security issues
and incorrect query syntax. This update affects the JDBC value processing logic and the
way columns are built into SQL queries, streamlining the escaping mechanism for various
data types.

The changes include:
- Removal of unnecessary null checks that were redundant with Objects.isNull().
- Streamlined string escaping logic using EasyStringUtils.escapeAndQuoteString().- Utilization of the stream API for more concise and readable code.

BREAKING CHANGE: If any external code relies on the previous behavior of not escaping
string values, it must now handle the escaped values appropriately to avoid syntax
errors or potential SQL injection vulnerabilities.
This commit is contained in:
zgq
2024-07-08 17:01:42 +08:00
parent 6e3b58a8f1
commit ec9121bf35
12 changed files with 251 additions and 38 deletions

View File

@ -1,9 +1,14 @@
package ai.chat2db.plugin.oracle.value;
import ai.chat2db.plugin.oracle.type.OracleColumnTypeEnum;
import ai.chat2db.plugin.oracle.value.factory.OracleValueProcessorFactory;
import ai.chat2db.server.tools.common.util.EasyStringUtils;
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
/**
* @author: zgq
@ -12,6 +17,41 @@ import ai.chat2db.spi.model.SQLDataValue;
public class OracleValueProcessor extends DefaultValueProcessor {
@Override
public String getJdbcValue(JDBCDataValue dataValue) {
if (OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName().equalsIgnoreCase(dataValue.getType())) {
return convertJDBCValueByType(dataValue);
}
Object value = dataValue.getObject();
if (Objects.isNull(value)) {
return null;
}
if (value instanceof String emptyStr) {
if (StringUtils.isBlank(emptyStr)) {
return emptyStr;
}
}
return convertJDBCValueByType(dataValue);
}
@Override
public String getJdbcValueString(JDBCDataValue dataValue) {
if (OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName().equalsIgnoreCase(dataValue.getType())) {
return convertJDBCValueStrByType(dataValue);
}
Object value = dataValue.getObject();
if (Objects.isNull(value)) {
return "NULL";
}
if (value instanceof String stringValue) {
if (StringUtils.isBlank(stringValue)) {
return EasyStringUtils.quoteString(stringValue);
}
}
return convertJDBCValueStrByType(dataValue);
}
@Override
public String convertSQLValueByType(SQLDataValue dataValue) {
return OracleValueProcessorFactory.getValueProcessor(dataValue.getDateTypeName()).convertSQLValueByType(dataValue);

View File

@ -39,9 +39,11 @@ public class OracleValueProcessorFactory {
Map.entry(OracleColumnTypeEnum.BLOB.name(), oracleBlobProcessor),
//raw
Map.entry(OracleColumnTypeEnum.RAW.name(), oracleRawValueProcessor),
Map.entry(OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName(), oracleRawValueProcessor),
//long raw
Map.entry(OracleColumnTypeEnum.LONG_RAW.getColumnType().getTypeName(), new OracleLongRawProcessor()),
//xml
Map.entry("SYS.XMLTYPE", new OracleXmlValueProcessor())
Map.entry("SYS.XMLTYPE", new OracleXmlValueProcessor()),
Map.entry("SYS.ANYDATA", new OracleAnyDataProcessor())
);
}

View File

@ -0,0 +1,49 @@
package ai.chat2db.plugin.oracle.value.sub;
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue;
/**
* @author: zgq
* @date: 2024年07月07日 10:42
*/
public class OracleAnyDataProcessor extends DefaultValueProcessor {
/**
* @param dataValue
* @return
*/
@Override
public String convertSQLValueByType(SQLDataValue dataValue) {
return dataValue.getValue();
}
@Override
public String convertJDBCValueByType(JDBCDataValue dataValue) {
// byte[] bytes = dataValue.getBytes();
// int length = bytes.length;
// String rawString = new String(bytes);
//
// // Filter printable characters
// StringBuilder printableString = new StringBuilder();
// for (char c : rawString.toCharArray()) {
// if (c >= 32 && c <= 126) { // ASCII printable characters range
// printableString.append(c);
// }
// }
return "SYS.ANYDATA";
}
/**
* @param dataValue
* @return
*/
@Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return "SYS.ANYDATA";
}
}

View File

@ -0,0 +1,31 @@
package ai.chat2db.plugin.oracle.value.sub;
import ai.chat2db.server.tools.common.util.EasyStringUtils;
import ai.chat2db.spi.jdbc.DefaultValueProcessor;
import ai.chat2db.spi.model.JDBCDataValue;
import ai.chat2db.spi.model.SQLDataValue;
/**
* @author: zgq
* @date: 2024年07月07日 16:58
*/
public class OracleLongRawProcessor extends DefaultValueProcessor {
@Override
public String convertSQLValueByType(SQLDataValue dataValue) {
return EasyStringUtils.quoteString(dataValue.getValue());
}
@Override
public String convertJDBCValueByType(JDBCDataValue dataValue) {
return dataValue.getBinaryDataString();
}
@Override
public String convertJDBCValueStrByType(JDBCDataValue dataValue) {
return EasyStringUtils.quoteString(dataValue.getBlobHexString());
}
}