From 75ef3c520ec75b3bd3ffe781302cf38e38751626 Mon Sep 17 00:00:00 2001 From: mattthew Date: Fri, 24 Apr 2026 14:02:28 -0400 Subject: [PATCH] Fix whitespace sensitivity issues Update tests --- edgraph/server.go | 16 +++++++++++++++- edgraph/server_test.go | 13 +++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/edgraph/server.go b/edgraph/server.go index 66f4ec67e69..c6556963de1 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -721,10 +721,22 @@ func validateCondValue(cond string) error { } lower := strings.ToLower(cond) - if !strings.HasPrefix(lower, "@if(") && !strings.HasPrefix(lower, "@filter(") { + if !strings.HasPrefix(lower, "@if") && !strings.HasPrefix(lower, "@filter") { return errors.Errorf("invalid cond value: must start with @if( or @filter(") } + // Strip the directive prefix and verify the remainder (after optional whitespace) starts with '('. + prefix := "@if" + if strings.HasPrefix(lower, "@filter") { + prefix = "@filter" + } + rest := strings.TrimSpace(cond[len(prefix):]) + if len(rest) == 0 || rest[0] != '(' { + return errors.Errorf("invalid cond value: must start with @if( or @filter(") + } + // Rebuild cond without the space so the paren-balancing logic works on the normalized form. + cond = prefix + rest + openIdx := strings.Index(cond, "(") if openIdx == -1 { return errors.Errorf("invalid cond value: missing opening parenthesis") @@ -781,6 +793,7 @@ var valVarRegexp = regexp.MustCompile(`^val\([a-zA-Z_][a-zA-Z0-9_.]*\)$`) // validateValObjectId checks that an ObjectId starting with "val(" is a well-formed // val(variableName) reference and contains no injected DQL syntax. func validateValObjectId(objectId string) error { + objectId = strings.TrimSpace(objectId) if !valVarRegexp.MatchString(objectId) { return errors.Errorf("invalid val() reference in ObjectId: %q", objectId) } @@ -792,6 +805,7 @@ var langTagRegexp = regexp.MustCompile(`^[a-zA-Z]+(-[a-zA-Z0-9]+)*$`) // validateLangTag checks that a language tag contains only safe characters. func validateLangTag(lang string) error { + lang = strings.TrimSpace(lang) if lang == "" { return nil } diff --git a/edgraph/server_test.go b/edgraph/server_test.go index f8962fbe628..61bfaf7b09f 100644 --- a/edgraph/server_test.go +++ b/edgraph/server_test.go @@ -388,6 +388,11 @@ func TestValidateCondValue(t *testing.T) { `@if(not(eq(len(v), 0)))`, `@if(eq(name, "has (parens) inside"))`, `@filter(eq(len(v), 0))`, + // Spaces between directive and opening paren should be allowed (issue #9687). + `@if (eq(len(v), 0))`, + `@if (eq(len(v), 0))`, + `@filter (eq(len(v), 0))`, + ` @if ( NOT eq(len(RoutesId), 0) ) `, } for _, c := range valid { require.NoError(t, validateCondValue(c), "expected valid: %q", c) @@ -430,6 +435,10 @@ func TestValidateValObjectId(t *testing.T) { "val(queryVariable)", "val(my_var_123)", "val(Amt)", + // Leading/trailing whitespace should be tolerated. + " val(v)", + "val(v) ", + " val(v) ", } for _, v := range valid { require.NoError(t, validateValObjectId(v), "expected valid: %q", v) @@ -454,6 +463,10 @@ func TestValidateLangTag(t *testing.T) { "fr", "zh-Hans", "en-US", + // Leading/trailing whitespace should be tolerated. + " en", + "en ", + " en ", } for _, v := range valid { require.NoError(t, validateLangTag(v), "expected valid: %q", v)