Compare commits

..

2 Commits

Author SHA1 Message Date
lilleman 71cccaf4c9 Reject a leading quote that opens no JSON, and give the inline walk one home
Tests / vet + fmt + tests (pull_request) Successful in 55s
2026-09-03 20:43:04 +02:00
lilleman 704d18d109 Tests: a leading quote that opens no JSON names neither a template nor a path 2026-09-03 20:42:34 +02:00
3 changed files with 17 additions and 9 deletions
+1 -1
View File
@@ -279,7 +279,7 @@ func classify(arg string) (argKind, error) {
if strings.ContainsRune(arg, '{') || (isJSONStart(arg) && json.Valid([]byte(arg))) { if strings.ContainsRune(arg, '{') || (isJSONStart(arg) && json.Valid([]byte(arg))) {
return argTemplate, nil return argTemplate, nil
} }
if i := strings.IndexAny(arg, "[]"); i >= 0 { if i := strings.IndexAny(arg, `[]"`); i >= 0 {
return argPath, fmt.Errorf("%q holds a %q, which no path may, and it is not valid JSON, so it names no template either", arg, arg[i:i+1]) return argPath, fmt.Errorf("%q holds a %q, which no path may, and it is not valid JSON, so it names no template either", arg, arg[i:i+1])
} }
return argPath, nil return argPath, nil
+11 -4
View File
@@ -305,7 +305,6 @@ func TestClassify(t *testing.T) {
for arg, want := range map[string]argKind{ for arg, want := range map[string]argKind{
"sv_SE.person": argPath, "sv_SE.person": argPath,
"person.last": argPath, "person.last": argPath,
`"abc`: argPath, // a quote opening no JSON string is part of a name
"name: {x}": argTemplate, // a { token: a path can never carry a brace "name: {x}": argTemplate, // a { token: a path can never carry a brace
`{"format":"x"}`: argTemplate, `{"format":"x"}`: argTemplate,
`["a","b"]`: argTemplate, // a JSON array carries no brace `["a","b"]`: argTemplate, // a JSON array carries no brace
@@ -317,9 +316,17 @@ func TestClassify(t *testing.T) {
t.Errorf("classify(%q) = %v, %v; want %v", arg, got, err, want) t.Errorf("classify(%q) = %v, %v; want %v", arg, got, err, want)
} }
} }
for _, arg := range []string{"[abc]", "[abc].field", "x[1]", "a]b"} { for arg, want := range map[string]string{
if _, err := classify(arg); err == nil { "[abc]": `holds a "["`,
t.Errorf("classify(%q) = no error; want the bracket rejected", arg) "[abc].field": `holds a "["`,
"x[1]": `holds a "["`,
"a]b": `holds a "]"`,
`"abc`: `holds a "\""`,
`"a]b`: `holds a "\""`, // the opener the reader typed, not the bracket behind it
} {
_, err := classify(arg)
if err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("classify(%q) = %v; want it rejected naming %s", arg, err, want)
} }
} }
} }
+5 -4
View File
@@ -36,10 +36,11 @@ func (f *Generator) NewTemplate(input string) (*Template, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("fejkdata: %w", err) return nil, fmt.Errorf("fejkdata: %w", err)
} }
if err := linkNodeRefs(n, f.categories); err != nil { scope := inlineScope(n)
if err := linkNodeRefs(scope, f.categories); err != nil {
return nil, fmt.Errorf("fejkdata: %w", err) return nil, fmt.Errorf("fejkdata: %w", err)
} }
if err := checkScope(inlineScope(n)); err != nil { if err := checkScope(scope); err != nil {
return nil, fmt.Errorf("fejkdata: %w", err) return nil, fmt.Errorf("fejkdata: %w", err)
} }
return &Template{g: f, n: n}, nil return &Template{g: f, n: n}, nil
@@ -77,8 +78,8 @@ func compileInput(input string) (node, error) {
// linkNodeRefs binds the references in an inline node's templates against the // linkNodeRefs binds the references in an inline node's templates against the
// loaded tree. An inline template sits in no folder, so . and .. name nothing and // loaded tree. An inline template sits in no folder, so . and .. name nothing and
// are rejected for the root spelling they would otherwise silently mean. // are rejected for the root spelling they would otherwise silently mean.
func linkNodeRefs(n node, root map[string]node) error { func linkNodeRefs(scope nodeScope, root map[string]node) error {
return eachNode(n, "template", func(path string, m node) error { return scope(func(path string, m node) error {
t, ok := m.(*template) t, ok := m.(*template)
if !ok { if !ok {
return nil return nil