1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.scripting.xmltags;
17
18 import java.util.regex.Pattern;
19
20 import org.apache.ibatis.parsing.GenericTokenParser;
21 import org.apache.ibatis.parsing.TokenHandler;
22 import org.apache.ibatis.scripting.ScriptingException;
23 import org.apache.ibatis.type.SimpleTypeRegistry;
24
25
26
27
28 public class TextSqlNode implements SqlNode {
29 private final String text;
30 private final Pattern injectionFilter;
31
32 public TextSqlNode(String text) {
33 this(text, null);
34 }
35
36 public TextSqlNode(String text, Pattern injectionFilter) {
37 this.text = text;
38 this.injectionFilter = injectionFilter;
39 }
40
41 public boolean isDynamic() {
42 DynamicCheckerTokenParser checker = new DynamicCheckerTokenParser();
43 GenericTokenParser parser = createParser(checker);
44 parser.parse(text);
45 return checker.isDynamic();
46 }
47
48 @Override
49 public boolean apply(DynamicContext context) {
50 GenericTokenParser parser = createParser(new BindingTokenParser(context, injectionFilter));
51 context.appendSql(parser.parse(text));
52 return true;
53 }
54
55 private GenericTokenParser createParser(TokenHandler handler) {
56 return new GenericTokenParser("${", "}", handler);
57 }
58
59 private static class BindingTokenParser implements TokenHandler {
60
61 private final DynamicContext context;
62 private final Pattern injectionFilter;
63
64 public BindingTokenParser(DynamicContext context, Pattern injectionFilter) {
65 this.context = context;
66 this.injectionFilter = injectionFilter;
67 }
68
69 @Override
70 public String handleToken(String content) {
71 Object parameter = context.getBindings().get("_parameter");
72 if (parameter == null) {
73 context.getBindings().put("value", null);
74 } else if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {
75 context.getBindings().put("value", parameter);
76 }
77 Object value = OgnlCache.getValue(content, context.getBindings());
78 String srtValue = value == null ? "" : String.valueOf(value);
79 checkInjection(srtValue);
80 return srtValue;
81 }
82
83 private void checkInjection(String value) {
84 if (injectionFilter != null && !injectionFilter.matcher(value).matches()) {
85 throw new ScriptingException("Invalid input. Please conform to regex" + injectionFilter.pattern());
86 }
87 }
88 }
89
90 private static class DynamicCheckerTokenParser implements TokenHandler {
91
92 private boolean isDynamic;
93
94 public DynamicCheckerTokenParser() {
95
96 }
97
98 public boolean isDynamic() {
99 return isDynamic;
100 }
101
102 @Override
103 public String handleToken(String content) {
104 this.isDynamic = true;
105 return null;
106 }
107 }
108
109 }