Skip to content

Commit

Permalink
Merge pull request #7 from 3scale/filter-iterator
Browse files Browse the repository at this point in the history
array filters should not crash on strings
  • Loading branch information
mikz authored Oct 8, 2018
2 parents ce79ebf + 74c185d commit dcf3a4a
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 16 deletions.
45 changes: 31 additions & 14 deletions lib/liquid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2777,33 +2777,52 @@ function FilterSet:find_filter( filter_name )
return self.filterset[filter_name]
end
end

local function is_iterator(o)
local mt = getmetatable(o)

return mt and mt.__ipairs
end

local function iterator(o)
if type(o) == 'table' or is_iterator(o) then
return o
else
return { o }
end
end

--=== array filter begin
local function join( a, b)
-- body
return Interpreter:safe_concat(a, b)
return Interpreter:safe_concat(iterator(a), b or ' ')
end
local function first( a )
-- body
return a[1]
return iterator(a)[1]
end
local function size( a )
-- body
return(#iterator(a))
end
local function last( a )
-- body
return a[#a]
return iterator(a)[size(a)]
end
local function concat( a, b)
-- body
local temp = {}
for i,v in ipairs(a) do
for i,v in ipairs(iterator(a)) do
table.insert(temp, v)
end
for i,v in ipairs(b) do
for i,v in ipairs(iterator(b)) do
table.insert(temp, v)
end
return temp
end
local function index( a, b)
-- body
return a[(b + 1)]
return iterator(a)[(b + 1)]
end
local function map( a, map_field)
-- body
Expand All @@ -2816,20 +2835,18 @@ end
local function reverse( a )
-- body
local temp = {}
local num = #a
local it = iterator(a)
local num = size(a)
for k = num, 1, -1 do
table.insert(temp, a[k])
table.insert(temp, it[k])
end
return temp
end
local function size( a )
-- body
return(#a)
end

local function sort( a, sort_field)
-- body
local t = {}
for i,v in ipairs(a) do
for i,v in ipairs(iterator(a)) do
table.insert(t, v)
end
if not sort_field then
Expand All @@ -2845,7 +2862,7 @@ local function uniq( a )
-- body
local t = {}
local result = {}
for i,v in ipairs(a) do
for i,v in ipairs(iterator(a)) do
local k = cjson.encode(v)
if not t[k] then
t[k] = true
Expand Down
172 changes: 170 additions & 2 deletions t/array_filters.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ plan tests => repeat_each() * (3 * blocks());

my $pwd = cwd();

our $HttpConfig = qq{
our $HttpConfig = qq|
lua_package_path "$pwd/lib/?.lua;;;";
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
};
init_by_lua_block { Liquid = require 'liquid' }
|;


no_long_string();
Expand Down Expand Up @@ -264,3 +265,170 @@ GET /t
--- no_error_log
[error]
=== TEST 11: 'join' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- str | join: ' - ' -}}
]]):render(Liquid.InterpreterContext:new({ str = "string" })) )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 12: 'first' filter works strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- str | first -}}
]]):render(Liquid.InterpreterContext:new({ str = "string" })) )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 13: 'last' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- str | last -}}
]]):render( Liquid.InterpreterContext:new({ str = "string" })) )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 14: 'concat' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{%- assign a = "string" | concat:(1..3) -%}
{%- assign b = "string" | concat: "another" -%}
{%- for k in a %} {{k}} {%- endfor -%}
{%- for k in b %} {{k}} {%- endfor -%}
]]):render())
}
}
--- request
GET /t
--- response_body
string 1 2 3 string another
--- no_error_log
[error]
=== TEST 5: 'index' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- "string"| index: 0 -}}
]]):render() )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 16: 'reverse' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- "string" | reverse | join -}}
]]):render() )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 17: 'size' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- "string" | size -}}
]]):render() )
}
}
--- request
GET /t
--- response_body
1
--- no_error_log
[error]
=== TEST 18: 'sort' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- "string" | sort | join -}}
]]):render() )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]
=== TEST 19: 'uniq' filter works on strings
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
ngx.say( Liquid.Template:parse([[
{{- "string" | uniq | join -}}
]]):render() )
}
}
--- request
GET /t
--- response_body
string
--- no_error_log
[error]

0 comments on commit dcf3a4a

Please sign in to comment.