Skip to content

Commit bff0d44

Browse files
committed
@combine:value 复杂条件组合:解决最终条件丢失 id, id{},解决可以通过 !id, !id{} 绕过权限校验
1 parent 4cf7d98 commit bff0d44

1 file changed

Lines changed: 62 additions & 28 deletions

File tree

APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,8 @@ public String getWhereString(boolean hasPrefix, RequestMethod method, Map<String
23572357

23582358
int maxWhereCount = getMaxWhereCount();
23592359
if (maxWhereCount > 0 && whereSize > maxWhereCount) {
2360-
throw new IllegalArgumentException(table + ":{ key0:value0, key1:value1... } 中条件 key:value 数量 " + whereSize + " 已超过最大数量,必须在 0-" + maxWhereCount + " 内!");
2360+
throw new IllegalArgumentException(table + ":{ key0:value0, key1:value1... } 中条件 key:value 数量 " + whereSize
2361+
+ " 已超过最大数量,必须在 0-" + maxWhereCount + " 内!");
23612362
}
23622363

23632364
String whereString = "";
@@ -2367,6 +2368,9 @@ public String getWhereString(boolean hasPrefix, RequestMethod method, Map<String
23672368
int maxCombineKeyCount = getMaxCombineKeyCount();
23682369
float maxCombineRatio = getMaxCombineRatio();
23692370

2371+
List<Object> prepreadValues = getPreparedValueList();
2372+
setPreparedValueList(new ArrayList<>());
2373+
23702374
int depth = 0;
23712375
int allCount = 0;
23722376

@@ -2394,8 +2398,8 @@ public String getWhereString(boolean hasPrefix, RequestMethod method, Map<String
23942398

23952399
if (isEmpty == false) {
23962400
if (first == false && lastLogic <= 0) {
2397-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(i - key.length() - (isOver ? 1 : 0))
2398-
+ "' 不合法!左边缺少 & | ! 其中一个逻辑连接符!");
2401+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 "
2402+
+ "'" + s.substring(i - key.length() - (isOver ? 1 : 0)) + "' 不合法!左边缺少 & | 其中一个逻辑连接符!");
23992403
}
24002404

24012405
allCount ++;
@@ -2413,19 +2417,21 @@ public String getWhereString(boolean hasPrefix, RequestMethod method, Map<String
24132417

24142418
Object value = where.get(column);
24152419
if (value == null) {
2416-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + key + "' 对应的条件键值对 " + column + ":value 不存在!");
2420+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + key
2421+
+ "' 对应的条件键值对 " + column + ":value 不存在!");
24172422
}
24182423

24192424
String wi = getWhereItem(column, value, method, verifyName);
24202425
if (StringUtil.isEmpty(wi, true)) { // 转成 1=1 ?
2421-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + key + "' 对应的 " + column + ":value 不是有效条件键值对!");
2426+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + key
2427+
+ "' 对应的 " + column + ":value 不是有效条件键值对!");
24222428
}
24232429

24242430
Integer count = usedKeyCountMap.get(column);
24252431
count = count == null ? 1 : count + 1;
24262432
if (count > maxCombineKeyCount && maxCombineKeyCount > 0) {
2427-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s + "' 不合法!其中 '" + column
2428-
+ "' 重复引用,次数 " + count + " 已超过最大值,必须在 0-" + maxCombineKeyCount + " 内!");
2433+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s + "' 不合法!"
2434+
+ "其中 '" + column + "' 重复引用,次数 " + count + " 已超过最大值,必须在 0-" + maxCombineKeyCount + " 内!");
24292435
}
24302436
usedKeyCountMap.put(column, count);
24312437

@@ -2476,8 +2482,24 @@ else if (c == '|') {
24762482
}
24772483
}
24782484
else if (c == '!') {
2479-
last = i < 1 ? 0 : s.charAt(i - 1); // & | 后面跳过了空格
2480-
if (i < n - 1 && s.charAt(i + 1) == '(') {
2485+
char next = i >= n - 1 ? 0 : s.charAt(i + 1);
2486+
if (next == ' ') {
2487+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1)
2488+
+ "' 不合法!非逻辑符 '!' 右边多了一个空格 ' ' !非逻辑符 '!' 右边不允许任何相邻空格 ' ',也不允许 ')' '&' '|' 中任何一个!");
2489+
}
2490+
if (next == ')' || next == '&' || next == '!') {
2491+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1)
2492+
+ "' 不合法!非逻辑符 '!' 右边多了一个字符 '" + next + "' !非逻辑符 '!' 右边不允许任何相邻空格 ' ',也不允许 ')' '&' '|' 中任何一个!");
2493+
}
2494+
2495+
last = i <= 0 ? 0 : s.charAt(i - 1); // & | 后面跳过了空格
2496+
if (i > 0 && lastLogic <= 0 && last != '(') {
2497+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(i)
2498+
+ "' 不合法!左边缺少 & | 逻辑连接符!逻辑连接符 & | 左右必须各一个相邻空格!空格不能多也不能少!"
2499+
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
2500+
}
2501+
2502+
if (next == '(') {
24812503
whereString += SQL.NOT;
24822504
lastLogic = c;
24832505
}
@@ -2491,12 +2513,15 @@ else if (last <= 0 || last == ' ' || last == '(') {
24912513
}
24922514
else if (c == '(') {
24932515
if (key.isEmpty() == false || (i > 0 && lastLogic <= 0 && last != '(')) {
2494-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(i) + "' 不合法!左边缺少 & | 逻辑连接符!");
2516+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(i)
2517+
+ "' 不合法!左边缺少 & | 逻辑连接符!逻辑连接符 & | 左右必须各一个相邻空格!空格不能多也不能少!"
2518+
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
24952519
}
24962520

24972521
depth ++;
24982522
if (depth > maxDepth && maxDepth > 0) {
2499-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1) + "' 不合法!括号 (()) 嵌套层级 " + depth + " 已超过最大值,必须在 0-" + maxDepth + " 内!");
2523+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1)
2524+
+ "' 不合法!括号 (()) 嵌套层级 " + depth + " 已超过最大值,必须在 0-" + maxDepth + " 内!");
25002525
}
25012526

25022527
whereString += c;
@@ -2506,7 +2531,8 @@ else if (c == '(') {
25062531
else if (c == ')') {
25072532
depth --;
25082533
if (depth < 0) {
2509-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1) + "' 不合法!左括号 ( 比 右括号 ) 少!数量必须相等从而完整闭合 (...) !");
2534+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s.substring(0, i + 1)
2535+
+ "' 不合法!左括号 ( 比 右括号 ) 少!数量必须相等从而完整闭合 (...) !");
25102536
}
25112537

25122538
whereString += c;
@@ -2521,7 +2547,8 @@ else if (c == ')') {
25212547
}
25222548

25232549
if (depth != 0) {
2524-
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s + "' 不合法!左括号 ( 比 右括号 ) 多!数量必须相等从而完整闭合 (...) !");
2550+
throw new IllegalArgumentException(table + ":{ @combine: '" + combine + "' } 中字符 '" + s
2551+
+ "' 不合法!左括号 ( 比 右括号 ) 多!数量必须相等从而完整闭合 (...) !");
25252552
}
25262553

25272554
Set<Entry<String, Object>> set = where.entrySet();
@@ -2548,7 +2575,11 @@ else if (c == ')') {
25482575
whereString = andWhere;
25492576
}
25502577
else if (StringUtil.isNotEmpty(andWhere, true)) { // andWhere 必须放后面,否则 prepared 值顺序错误
2551-
whereString = "( " + whereString + " )" + AND + andWhere;
2578+
// whereString = "( " + whereString + " )" + AND + andWhere;
2579+
2580+
whereString = andWhere + AND + "( " + whereString + " )"; // 先暂存之前的 prepared 值,然后反向整合
2581+
prepreadValues.addAll(getPreparedValueList());
2582+
setPreparedValueList(prepreadValues);
25522583
}
25532584

25542585
if (joinList != null) {
@@ -2557,7 +2588,7 @@ else if (StringUtil.isNotEmpty(andWhere, true)) { // andWhere 必须放后面
25572588
String ws = whereString;
25582589

25592590
List<Object> newPvl = new ArrayList<>();
2560-
List<Object> pvl = new ArrayList<>(preparedValueList);
2591+
List<Object> pvl = new ArrayList<>(getPreparedValueList());
25612592

25622593
SQLConfig jc;
25632594
String js;
@@ -2673,7 +2704,7 @@ else if (isSideJoin) { // ^ SIDE JOIN: ! (A & B)
26732704

26742705
if (changed) {
26752706
whereString = newWs;
2676-
preparedValueList = newPvl;
2707+
setPreparedValueList(newPvl);
26772708
}
26782709
}
26792710

@@ -4199,6 +4230,20 @@ else if (id instanceof Subquery) {}
41994230
List<String> orList = combineMap == null ? null : new ArrayList<>();
42004231
List<String> notList = combineMap == null ? null : new ArrayList<>();
42014232

4233+
//强制作为条件且放在最前面优化性能
4234+
if (id != null) {
4235+
tableWhere.put(idKey, id);
4236+
if (andList != null) {
4237+
andList.add(idKey);
4238+
}
4239+
}
4240+
if (idIn != null) {
4241+
tableWhere.put(idInKey, idIn);
4242+
if (andList != null) {
4243+
andList.add(idInKey);
4244+
}
4245+
}
4246+
42024247
if (combineMap == null) {
42034248
if (StringUtil.isNotEmpty(combineExpression, true)) {
42044249
List<String> banKeyList = Arrays.asList(idKey, idInKey, userIdKey, userIdInKey);
@@ -4208,7 +4253,7 @@ else if (id instanceof Subquery) {}
42084253
if (index >= 0) {
42094254
char left = index <= 0 ? ' ' : combineExpression.charAt(index - 1);
42104255
char right = index >= combineExpression.length() - key.length() ? ' ' : combineExpression.charAt(index + key.length());
4211-
if ((left == ' ' || left == '(') && (right == ' ' || right == ')')) {
4256+
if ((left == ' ' || left == '(' || left == '&' || left == '|' || left == '!') && (right == ' ' || right == ')')) {
42124257
throw new UnsupportedOperationException(table + ":{} 里的 @combine:value 中的 value 里 " + key + " 不合法!"
42134258
+ "不允许传 [" + idKey + ", " + idInKey + ", " + userIdKey + ", " + userIdInKey + "] 其中任何一个!");
42144259
}
@@ -4217,17 +4262,6 @@ else if (id instanceof Subquery) {}
42174262
}
42184263
}
42194264
else {
4220-
//强制作为条件且放在最前面优化性能
4221-
if (id != null) {
4222-
tableWhere.put(idKey, id);
4223-
andList.add(idKey);
4224-
}
4225-
if (idIn != null) {
4226-
tableWhere.put(idInKey, idIn);
4227-
andList.add(idInKey);
4228-
}
4229-
4230-
42314265
if (ws != null) {
42324266
if (method == DELETE || method == GETS || method == HEADS) {
42334267
throw new IllegalArgumentException("DELETE,GETS,HEADS 请求不允许传 @combine:value !");

0 commit comments

Comments
 (0)