Repository navigation
Expand file tree
/
Copy pathDeferredQueryHandler.java
More file actions
143 lines (126 loc) · 5.38 KB
/
Copy pathDeferredQueryHandler.java
File metadata and controls
143 lines (126 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.example;
import org.springframework.r2dbc.core.DatabaseClient;
/**
* Test source for the `DatabaseClient.sql(Supplier<String>)` overload: SQL
* text is deferred behind a lambda instead of being passed directly as a
* String.
*/
public class DeferredQueryHandler {
// Fake remote flow source, recognized by DatabaseClientSqlInjection.ql.
public static String source() {
return null;
}
private final DatabaseClient databaseClient;
public DeferredQueryHandler(DatabaseClient databaseClient) {
this.databaseClient = databaseClient;
}
public Object runDeferredQuery() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.fetch()
.all(); // sink 2: sql(Supplier<String>)
}
// Alternative terminal/execution-triggering method to fetch(): then().
public Object runDeferredQueryThen() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.then(); // sink: sql(Supplier<String>) via then()
}
// Alternative terminal method: map(...).all() instead of fetch().all(),
// matching the exact chain from the original real-world report.
public Object runDeferredQueryWithMap() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.map(row -> row)
.all(); // sink: sql(Supplier<String>) via map()
}
// Intermediate fluent bind() call between the deferred sql() and the
// terminal fetch() - taint must survive the fluent chain.
public Object runDeferredQueryWithBind() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.bind(0, "unrelated-value")
.fetch()
.all(); // sink: sql(Supplier<String>) via bind().fetch()
}
// Same as above but exercising the String-named bind() overload, to
// confirm the summary model's signature string matches the correct
// overload (not just the int-indexed one).
public Object runDeferredQueryWithBindByName() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.bind("param", "unrelated-value")
.fetch()
.all(); // sink: sql(Supplier<String>) via bind(String,Object).fetch()
}
// Alternative terminal method: flatMap(...), which returns Flux<R>
// directly instead of an intermediate RowsFetchSpec.
public Object runDeferredQueryWithFlatMap() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.flatMap(row -> row); // sink: sql(Supplier<String>) via flatMap()
}
// Alternative terminal method: map(BiFunction).
public Object runDeferredQueryWithMapBiFunction() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.map((row, meta) -> row)
.all(); // sink: sql(Supplier<String>) via map(BiFunction)
}
// Chains bindNull(int,Class), bindValues(List), bindProperties(Object),
// and filter(Function) before the mapValue(Class) terminal sink -
// validates the remaining summary/sink signature strings in one flow.
public Object runDeferredQueryWithBindNullAndFilter() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.bindNull(1, String.class)
.bindValues(java.util.List.of("unrelated"))
.bindProperties(new Object())
.filter(spec -> spec)
.mapValue(String.class)
.all(); // sink: sql(Supplier<String>) via mapValue() after bindNull/bindValues(List)/bindProperties/filter(Function)
}
// Isolated: bindNull(String,Class) alone.
public Object runDeferredQueryWithBindNullByName() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.bindNull("param", String.class)
.fetch()
.all(); // sink: sql(Supplier<String>) via bindNull(String,Class).fetch()
}
// Isolated: bindValues(Map) alone.
public Object runDeferredQueryWithBindValuesMap() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.bindValues(java.util.Map.of("param", "unrelated"))
.fetch()
.all(); // sink: sql(Supplier<String>) via bindValues(Map).fetch()
}
// Isolated: filter(StatementFilterFunction) alone.
public Object runDeferredQueryWithFilterOverload() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.filter((org.springframework.r2dbc.core.StatementFilterFunction) null)
.fetch()
.all(); // sink: sql(Supplier<String>) via filter(StatementFilterFunction).fetch()
}
// Isolated: mapProperties(Class) alone.
public Object runDeferredQueryWithMapProperties() {
String category = source();
return databaseClient
.sql(() -> "SELECT * FROM items WHERE category = '" + category + "'")
.mapProperties(String.class)
.all(); // sink: sql(Supplier<String>) via mapProperties()
}
}