Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions filter_tag_resolution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package pongo2_test

import (
"strings"
"testing"

"github.com/flosch/pongo2/v7"
)

func TestFilterTagResolvesFiltersAtParseTime(t *testing.T) {
t.Parallel()
tests := []struct {
name string
filter string
setup func(*pongo2.TemplateSet) error
want string
}{
{
name: "banned",
filter: "upper",
setup: func(set *pongo2.TemplateSet) error { return set.BanFilter("upper") },
want: "Usage of filter 'upper' is not allowed",
},
{
name: "unknown",
filter: "does_not_exist",
setup: func(*pongo2.TemplateSet) error { return nil },
want: "Filter 'does_not_exist' does not exist",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
set := pongo2.NewSet(test.name, &pongo2.DummyLoader{})
if err := test.setup(set); err != nil {
t.Fatalf("setup: %v", err)
}
_, err := set.FromString("{% filter " + test.filter + " %}body{% endfilter %}")
if err == nil || !strings.Contains(err.Error(), test.want) {
t.Fatalf("FromString error = %v, want %q", err, test.want)
}
})
}
}
17 changes: 13 additions & 4 deletions tags_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package pongo2

import (
"bytes"
"fmt"
)

// nodeFilterCall represents a single filter call with its name and optional parameter.
// nodeFilterCall represents one resolved filter with its optional parameter.
type nodeFilterCall struct {
name string
paramExpr IEvaluator
filter FilterFunction
}

// tagFilterNode represents the {% filter %} tag.
Expand Down Expand Up @@ -76,7 +77,7 @@ func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter)
} else {
param = AsValue(nil)
}
value, err = ctx.template.set.ApplyFilter(call.name, value, param)
value, err = call.filter(value, param)
if err != nil {
return ctx.Error(err.Error(), node.position)
}
Expand Down Expand Up @@ -111,7 +112,15 @@ func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, er
if nameToken == nil {
return nil, arguments.Error("Expected a filter name (identifier).", nil)
}
filterCall.name = nameToken.Val
if _, banned := doc.template.set.bannedFilters[nameToken.Val]; banned {
return nil, arguments.Error(fmt.Sprintf("Usage of filter '%s' is not allowed (sandbox restriction active).",
nameToken.Val), nameToken)
}
filter, exists := doc.template.set.filters[nameToken.Val]
if !exists {
return nil, arguments.Error(fmt.Sprintf("Filter '%s' does not exist.", nameToken.Val), nameToken)
}
filterCall.filter = filter

if arguments.MatchOne(TokenSymbol, ":") != nil {
// Filter parameter
Expand Down