fix(validation): enhance filter logic for column validation

* adjust handling of "all" filter to consider filtered columns
fix(function_api): improve variable substitution in SQL queries
* add safeSubstituteVar for context-aware value sanitization
This commit is contained in:
Hein
2026-05-27 12:17:31 +02:00
parent c4e79d6950
commit 4018af0636
2 changed files with 38 additions and 3 deletions
+5 -1
View File
@@ -236,7 +236,11 @@ func (v *ColumnValidator) FilterRequestOptions(options RequestOptions) RequestOp
validFilters := make([]FilterOption, 0, len(options.Filters)) validFilters := make([]FilterOption, 0, len(options.Filters))
for _, filter := range options.Filters { for _, filter := range options.Filters {
if strings.EqualFold(filter.Column, "all") { if strings.EqualFold(filter.Column, "all") {
for _, col := range v.Columns() { allCols := v.Columns()
if len(filtered.Columns) > 0 {
allCols = filtered.Columns
}
for _, col := range allCols {
expanded := filter expanded := filter
expanded.Column = col expanded.Column = col
expanded.LogicOperator = "OR" expanded.LogicOperator = "OR"
+33 -2
View File
@@ -174,7 +174,7 @@ func (h *Handler) SqlQueryList(sqlquery string, options SqlQueryOptions) HTTPFun
varName := kw[1 : len(kw)-1] // strip [ and ] varName := kw[1 : len(kw)-1] // strip [ and ]
if val, ok := variables[varName]; ok { if val, ok := variables[varName]; ok {
if strVal := fmt.Sprintf("%v", val); strVal != "" { if strVal := fmt.Sprintf("%v", val); strVal != "" {
sqlquery = strings.ReplaceAll(sqlquery, kw, ValidSQL(strVal, "colvalue")) sqlquery = strings.ReplaceAll(sqlquery, kw, safeSubstituteVar(sqlquery, kw, strVal))
continue continue
} }
} }
@@ -533,7 +533,7 @@ func (h *Handler) SqlQuery(sqlquery string, options SqlQueryOptions) HTTPFuncTyp
varName := kw[1 : len(kw)-1] // strip [ and ] varName := kw[1 : len(kw)-1] // strip [ and ]
if val, ok := variables[varName]; ok { if val, ok := variables[varName]; ok {
if strVal := fmt.Sprintf("%v", val); strVal != "" { if strVal := fmt.Sprintf("%v", val); strVal != "" {
sqlquery = strings.ReplaceAll(sqlquery, kw, ValidSQL(strVal, "colvalue")) sqlquery = strings.ReplaceAll(sqlquery, kw, safeSubstituteVar(sqlquery, kw, strVal))
continue continue
} }
} }
@@ -1006,6 +1006,37 @@ func IsNumeric(s string) bool {
return err == nil return err == nil
} }
// isInsideDollarQuote reports whether the first occurrence of placeholder in sqlquery
// is immediately surrounded by dollar-sign characters (i.e. inside a $...$-quoted string).
// Dollar-quoted strings pass content through literally — no backslash processing — so
// values placed there must NOT have their backslashes escaped.
func isInsideDollarQuote(sqlquery, placeholder string) bool {
idx := strings.Index(sqlquery, placeholder)
if idx < 0 {
return false
}
endIdx := idx + len(placeholder)
charBefore := byte(0)
charAfter := byte(0)
if idx > 0 {
charBefore = sqlquery[idx-1]
}
if endIdx < len(sqlquery) {
charAfter = sqlquery[endIdx]
}
return charBefore == '$' || charAfter == '$'
}
// safeSubstituteVar returns value sanitised for the quoting context that surrounds
// placeholder in sqlquery: raw (no backslash escaping) for dollar-quoted contexts,
// ValidSQL("colvalue") escaping for everything else.
func safeSubstituteVar(sqlquery, placeholder, value string) string {
if isInsideDollarQuote(sqlquery, placeholder) {
return value
}
return ValidSQL(value, "colvalue")
}
// getReplacementForBlankParam determines the replacement value for an unused parameter // getReplacementForBlankParam determines the replacement value for an unused parameter
// based on whether it appears within quotes in the SQL query. // based on whether it appears within quotes in the SQL query.
// It checks for PostgreSQL quotes: single quotes (”) and dollar quotes ($...$) // It checks for PostgreSQL quotes: single quotes (”) and dollar quotes ($...$)