PageRenderTime 42ms CodeModel.GetById 11ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/mod_base/filters/filter_force_escape.erl

https://code.google.com/p/zotonic/
Erlang | 95 lines | 60 code | 10 blank | 25 comment | 0 complexity | 77950b5ec2a0e7dc0cd9394f461e8ab5 MD5 | raw file
 1%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
 2%% @author    Evan Miller <emmiller@gmail.com>
 3%% @copyright 2008 Roberto Saccon, Evan Miller
 4%% @doc 'force_escape' filter, escape all html unsafe characters
 5
 6%%% The MIT License
 7%%%
 8%%% Copyright (c) 2007 Roberto Saccon, Evan Miller
 9%%%
10%%% Permission is hereby granted, free of charge, to any person obtaining a copy
11%%% of this software and associated documentation files (the "Software"), to deal
12%%% in the Software without restriction, including without limitation the rights
13%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14%%% copies of the Software, and to permit persons to whom the Software is
15%%% furnished to do so, subject to the following conditions:
16%%%
17%%% The above copyright notice and this permission notice shall be included in
18%%% all copies or substantial portions of the Software.
19%%%
20%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26%%% THE SOFTWARE.
27
28-module(filter_force_escape).
29-export([force_escape/2]).
30
31-author('rsaccon@gmail.com').
32-author('emmiller@gmail.com').
33
34
35force_escape(undefined, _Context) -> 
36    <<>>;
37force_escape(Input, _Context) when is_atom(Input) ->
38    escape1(atom_to_list(Input), []);
39force_escape(Input, _Context) when is_list(Input) ->
40    escape1(Input, []);
41force_escape(Input, _Context) when is_binary(Input) ->
42    escape1(Input, 0);
43force_escape(Input, _Context) when is_integer(Input) ->
44    integer_to_list(Input);
45force_escape({{Y,M,D}, {_H,_I,_S}} = Input, Context) when is_integer(Y) andalso is_integer(M) andalso is_integer(D) ->
46    filter_date:date(Input, "Y-m-d H:i:s", Context);
47force_escape({Y,M,D} = Input, Context) when is_integer(Y) andalso is_integer(M) andalso is_integer(D) ->
48    filter_date:date(Input, "Y-m-d", Context);
49force_escape(true, _Context) ->
50    filter_yesno:yesno(true, _Context);
51force_escape(false, _Context) ->
52    filter_yesno:yesno(false, _Context).
53    
54
55
56escape1(Binary, Index) when is_binary(Binary) ->
57    case Binary of
58        <<Pre:Index/binary, $<, Post/binary>> ->
59            process_binary_match(Pre, <<"&lt;">>, size(Post), escape1(Post, 0));
60        <<Pre:Index/binary, $>, Post/binary>> ->
61            process_binary_match(Pre, <<"&gt;">>, size(Post), escape1(Post, 0));
62        <<Pre:Index/binary, $&, Post/binary>> ->
63            process_binary_match(Pre, <<"&amp;">>, size(Post), escape1(Post, 0));
64        <<Pre:Index/binary, 34, Post/binary>> ->
65            process_binary_match(Pre, <<"&quot;">>, size(Post), escape1(Post, 0));
66        <<Pre:Index/binary, 39, Post/binary>> ->
67            process_binary_match(Pre, <<"&#039;">>, size(Post), escape1(Post, 0));
68        <<_:Index/binary, _, _/binary>> ->
69            escape1(Binary, Index + 1);
70        Binary ->
71            Binary
72    end;
73escape1([], Acc) ->
74    lists:reverse(Acc);
75escape1("<" ++ Rest, Acc) ->
76    escape1(Rest, lists:reverse("&lt;", Acc));
77escape1(">" ++ Rest, Acc) ->
78    escape1(Rest, lists:reverse("&gt;", Acc));
79escape1("&" ++ Rest, Acc) ->
80    escape1(Rest, lists:reverse("&amp;", Acc));
81escape1("\"" ++ Rest, Acc) ->
82    escape1(Rest, lists:reverse("&quot;", Acc));
83escape1("'" ++ Rest, Acc) ->
84    escape1(Rest, lists:reverse("&#039;", Acc));
85escape1([C | Rest], Acc) ->
86    escape1(Rest, [C | Acc]).
87
88
89process_binary_match(Pre, Insertion, SizePost, Post) ->
90    case {size(Pre), SizePost} of
91        {0, 0} -> Insertion;
92        {0, _} -> [Insertion, Post];
93        {_, 0} -> [Pre, Insertion];
94        _ -> [Pre, Insertion, Post]
95    end.