diff --git a/autotest/ogr/ogr_sql_test.py b/autotest/ogr/ogr_sql_test.py index 2d0e5505263c..289327045e71 100755 --- a/autotest/ogr/ogr_sql_test.py +++ b/autotest/ogr/ogr_sql_test.py @@ -2154,3 +2154,73 @@ def test_ogr_sql_kahan_babuska_eumaier_summation(input, expected_output): assert math.isnan(f["SUM_v"]) else: assert f["SUM_v"] == expected_output + + +@pytest.mark.parametrize( + "operator", ["+", "-", "*", "/", "%", "<", "<=", "=<", "=", "<>", ">", ">=", "=>"] +) +def test_ogr_sql_max_expr_depth(operator): + + ds = ogr.GetDriverByName("Memory").CreateDataSource("") + ds.CreateLayer("test") + with ds.ExecuteSQL("SELECT " + operator.join(["1"] * 127) + " FROM test") as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT " + operator.join(["1"] * 128) + " FROM test") + + +def test_ogr_sql_max_expr_depth_other(): + ds = ogr.GetDriverByName("Memory").CreateDataSource("") + ds.CreateLayer("test") + + with ds.ExecuteSQL( + "SELECT CAST(" + "+".join(["1"] * 126) + " AS CHARACTER) FROM test" + ) as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL( + "SELECT CAST(" + "+".join(["1"] * 127) + " AS CHARACTER) FROM test" + ) + + with ds.ExecuteSQL( + "SELECT 'a' IN (CAST(" + "+".join(["1"] * 125) + " AS CHARACTER)) FROM test" + ) as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL( + "SELECT 'a' IN (CAST(" + "+".join(["1"] * 126) + " AS CHARACTER)) FROM test" + ) + + with ds.ExecuteSQL("SELECT NOT " + "+".join(["1"] * 126) + " FROM test") as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT NOT " + "+".join(["1"] * 127) + " FROM test") + + with ds.ExecuteSQL("SELECT 1 AND " + "+".join(["1"] * 126) + " FROM test") as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT 1 AND " + "+".join(["1"] * 127) + " FROM test") + + with ds.ExecuteSQL("SELECT 1 OR " + "+".join(["1"] * 126) + " FROM test") as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT 1 OR " + "+".join(["1"] * 127) + " FROM test") + + with ds.ExecuteSQL("SELECT " + "+".join(["1"] * 126) + " IS NULL FROM test") as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT " + "+".join(["1"] * 127) + " IS NULL FROM test") + + with ds.ExecuteSQL( + "SELECT " + "+".join(["1"] * 125) + " IS NOT NULL FROM test" + ) as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT " + "+".join(["1"] * 126) + " IS NOT NULL FROM test") + + with ds.ExecuteSQL( + "SELECT SUBSTR('a', " + "+".join(["1"] * 126) + ") FROM test" + ) as _: + pass + with pytest.raises(Exception, match="Maximum expression depth reached"): + ds.ExecuteSQL("SELECT SUBSTR('a', " + "+".join(["1"] * 127) + ") FROM test") diff --git a/ogr/CMakeLists.txt b/ogr/CMakeLists.txt index 0197196a37a3..b979547599b9 100644 --- a/ogr/CMakeLists.txt +++ b/ogr/CMakeLists.txt @@ -202,7 +202,7 @@ add_custom_target(check_swq_parser_md5 ALL COMMAND ${CMAKE_COMMAND} "-DIN_FILE=swq_parser.y" "-DTARGET=generate_swq_parser" - "-DEXPECTED_MD5SUM=47b674ecca1fc71a50bc81d7d0bfa29d " + "-DEXPECTED_MD5SUM=c3eaca734f3005e73586cc697e481f94" "-DFILENAME_CMAKE=${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt" -P "${PROJECT_SOURCE_DIR}/cmake/helpers/check_md5sum.cmake" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" diff --git a/ogr/ogr_swq.h b/ogr/ogr_swq.h index 35372e69a321..69ce7b92d107 100644 --- a/ogr/ogr_swq.h +++ b/ogr/ogr_swq.h @@ -157,8 +157,7 @@ class CPL_UNSTABLE_API swq_expr_node void Dump(FILE *fp, int depth); swq_field_type Check(swq_field_list *, int bAllowFieldsInSecondaryTables, int bAllowMismatchTypeOnFieldComparison, - swq_custom_func_registrar *poCustomFuncRegistrar, - int depth = 0); + swq_custom_func_registrar *poCustomFuncRegistrar); swq_expr_node *Evaluate(swq_field_fetcher pfnFetcher, void *record, const swq_evaluation_context &sContext); swq_expr_node *Clone(); @@ -169,6 +168,8 @@ class CPL_UNSTABLE_API swq_expr_node void RebalanceAndOr(); + bool HasReachedMaxDepth() const; + swq_node_type eNodeType = SNT_CONSTANT; swq_field_type field_type = SWQ_INTEGER; @@ -199,6 +200,9 @@ class CPL_UNSTABLE_API swq_expr_node // after parsing. swq_col_def.bHidden captures it afterwards. bool bHidden = false; + // Recursive depth of this expression, taking into account papoSubExpr. + int nDepth = 1; + static CPLString QuoteIfNecessary(const CPLString &, char chQuote = '\''); static CPLString Quote(const CPLString &, char chQuote = '\''); }; diff --git a/ogr/swq_expr_node.cpp b/ogr/swq_expr_node.cpp index 322dd2065f60..12dc794fc8e6 100644 --- a/ogr/swq_expr_node.cpp +++ b/ogr/swq_expr_node.cpp @@ -222,6 +222,7 @@ swq_expr_node &swq_expr_node::operator=(const swq_expr_node &other) if (other.string_value) string_value = CPLStrdup(other.string_value); bHidden = other.bHidden; + nDepth = other.nDepth; } return *this; } @@ -258,6 +259,7 @@ swq_expr_node &swq_expr_node::operator=(swq_expr_node &&other) std::swap(geometry_value, other.geometry_value); std::swap(string_value, other.string_value); bHidden = other.bHidden; + nDepth = other.nDepth; } return *this; } @@ -286,6 +288,8 @@ void swq_expr_node::PushSubExpression(swq_expr_node *child) CPLRealloc(papoSubExpr, sizeof(void *) * nSubExprCount)); papoSubExpr[nSubExprCount - 1] = child; + + nDepth = std::max(nDepth, 1 + child->nDepth); } /************************************************************************/ @@ -307,19 +311,13 @@ void swq_expr_node::ReverseSubExpressions() /* Check argument types, etc. */ /************************************************************************/ -swq_field_type swq_expr_node::Check( - swq_field_list *poFieldList, int bAllowFieldsInSecondaryTables, - int bAllowMismatchTypeOnFieldComparison, - swq_custom_func_registrar *poCustomFuncRegistrar, int nDepth) +swq_field_type +swq_expr_node::Check(swq_field_list *poFieldList, + int bAllowFieldsInSecondaryTables, + int bAllowMismatchTypeOnFieldComparison, + swq_custom_func_registrar *poCustomFuncRegistrar) { - if (nDepth == 32) - { - CPLError(CE_Failure, CPLE_AppDefined, - "Too many recursion levels in expression"); - return SWQ_ERROR; - } - /* -------------------------------------------------------------------- */ /* Otherwise we take constants literally. */ /* -------------------------------------------------------------------- */ @@ -390,8 +388,7 @@ swq_field_type swq_expr_node::Check( { if (papoSubExpr[i]->Check(poFieldList, bAllowFieldsInSecondaryTables, bAllowMismatchTypeOnFieldComparison, - poCustomFuncRegistrar, - nDepth + 1) == SWQ_ERROR) + poCustomFuncRegistrar) == SWQ_ERROR) return SWQ_ERROR; } @@ -1163,4 +1160,13 @@ void swq_expr_node::PushNotOperationDownToStack() papoSubExpr[i]->PushNotOperationDownToStack(); } +/************************************************************************/ +/* HasReachedMaxDepth() */ +/************************************************************************/ + +bool swq_expr_node::HasReachedMaxDepth() const +{ + return nDepth == 128; +} + #endif // #ifndef DOXYGEN_SKIP diff --git a/ogr/swq_parser.cpp b/ogr/swq_parser.cpp index 8191470c0bbc..773d3e02ddbb 100644 --- a/ogr/swq_parser.cpp +++ b/ogr/swq_parser.cpp @@ -606,17 +606,17 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 109, 109, 110, 116, 123, 128, 133, 138, 145, - 153, 161, 169, 177, 185, 193, 201, 209, 217, 225, - 237, 246, 259, 267, 279, 288, 301, 310, 323, 332, - 345, 352, 364, 370, 377, 379, 382, 390, 403, 408, - 413, 417, 422, 427, 432, 467, 474, 481, 488, 495, - 502, 538, 546, 552, 559, 568, 586, 606, 607, 610, - 615, 621, 622, 624, 632, 633, 636, 646, 647, 650, - 651, 654, 663, 674, 689, 704, 725, 756, 791, 816, - 845, 851, 854, 856, 865, 866, 871, 872, 878, 885, - 886, 889, 890, 893, 899, 905, 912, 913, 920, 921, - 929, 939, 950, 961, 974, 985 + 0, 109, 109, 110, 116, 123, 128, 139, 150, 163, + 177, 191, 205, 219, 233, 247, 261, 275, 289, 303, + 321, 336, 355, 369, 387, 402, 421, 436, 455, 470, + 489, 502, 520, 532, 545, 547, 550, 558, 571, 576, + 581, 585, 590, 595, 600, 641, 654, 667, 680, 693, + 706, 742, 756, 768, 775, 784, 802, 822, 823, 826, + 831, 837, 838, 840, 848, 849, 852, 862, 863, 866, + 867, 870, 879, 890, 905, 920, 941, 972, 1007, 1032, + 1061, 1067, 1070, 1072, 1081, 1082, 1087, 1088, 1094, 1101, + 1102, 1105, 1106, 1109, 1115, 1121, 1128, 1129, 1136, 1137, + 1145, 1155, 1166, 1177, 1190, 1201 }; #endif @@ -1729,12 +1729,24 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 6: /* value_expr: value_expr "AND" value_expr */ { yyval = swq_create_and_or_or( SWQ_AND, yyvsp[-2], yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; case 7: /* value_expr: value_expr "OR" value_expr */ { yyval = swq_create_and_or_or( SWQ_OR, yyvsp[-2], yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1743,6 +1755,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1752,6 +1770,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1761,6 +1785,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1770,6 +1800,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1779,6 +1815,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1788,6 +1830,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1797,6 +1845,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1806,6 +1860,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1815,6 +1875,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1824,6 +1890,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-3] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1833,6 +1905,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1846,6 +1924,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( like ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1856,6 +1940,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->PushSubExpression( yyvsp[-4] ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1870,6 +1960,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( like ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1879,6 +1975,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1892,6 +1994,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( like ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1902,6 +2010,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->PushSubExpression( yyvsp[-4] ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1916,6 +2030,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( like ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1926,6 +2046,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->nOperation = SWQ_IN; yyval->PushSubExpression( yyvsp[-4] ); yyval->ReverseSubExpressions(); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1940,6 +2066,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( in ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1950,6 +2082,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval->PushSubExpression( yyvsp[-4] ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1964,6 +2102,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( between ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1972,6 +2116,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_ISNULL ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( yyvsp[-2] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1984,13 +2134,25 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_NOT ); yyval->field_type = SWQ_BOOLEAN; yyval->PushSubExpression( isnull ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; case 32: /* value_expr_list: value_expr ',' value_expr_list */ { yyval = yyvsp[0]; - yyvsp[0]->PushSubExpression( yyvsp[-2] ); + yyval->PushSubExpression( yyvsp[-2] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -1998,6 +2160,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyval = new swq_expr_node( SWQ_ARGUMENT_LIST ); /* temporary value */ yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2091,6 +2259,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_MULTIPLY ); yyval->PushSubExpression( new swq_expr_node(-1) ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } } break; @@ -2100,6 +2274,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_ADD ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2108,6 +2288,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_SUBTRACT ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2116,6 +2302,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_MULTIPLY ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2124,6 +2316,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_DIVIDE ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2132,6 +2330,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = new swq_expr_node( SWQ_MODULUS ); yyval->PushSubExpression( yyvsp[-2] ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2177,6 +2381,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyval = yyvsp[-1]; yyval->PushSubExpression( yyvsp[-3] ); yyval->ReverseSubExpressions(); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; @@ -2184,6 +2394,12 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyval = new swq_expr_node( SWQ_CAST ); yyval->PushSubExpression( yyvsp[0] ); + if( yyval->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete yyval; + YYERROR; + } } break; diff --git a/ogr/swq_parser.y b/ogr/swq_parser.y index d7d51e7b469b..ac681d714154 100644 --- a/ogr/swq_parser.y +++ b/ogr/swq_parser.y @@ -128,11 +128,23 @@ value_expr: | value_expr SWQT_AND value_expr { $$ = swq_create_and_or_or( SWQ_AND, $1, $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_OR value_expr { $$ = swq_create_and_or_or( SWQ_OR, $1, $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | SWQT_NOT value_expr @@ -140,6 +152,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $2 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '=' value_expr @@ -148,6 +166,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '<' '>' value_expr @@ -156,6 +180,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '!' '=' value_expr @@ -164,6 +194,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '<' value_expr @@ -172,6 +208,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '>' value_expr @@ -180,6 +222,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '<' '=' value_expr @@ -188,6 +236,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '=' '<' value_expr @@ -196,6 +250,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '=' '>' value_expr @@ -204,6 +264,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr '>' '=' value_expr @@ -212,6 +278,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $4 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_LIKE value_expr @@ -220,6 +292,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_LIKE value_expr @@ -232,6 +310,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( like ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_LIKE value_expr SWQT_ESCAPE value_expr @@ -241,6 +325,12 @@ value_expr: $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); $$->PushSubExpression( $5 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_LIKE value_expr SWQT_ESCAPE value_expr @@ -254,6 +344,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( like ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_ILIKE value_expr @@ -262,6 +358,12 @@ value_expr: $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_ILIKE value_expr @@ -274,6 +376,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( like ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_ILIKE value_expr SWQT_ESCAPE value_expr @@ -283,6 +391,12 @@ value_expr: $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); $$->PushSubExpression( $5 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_ILIKE value_expr SWQT_ESCAPE value_expr @@ -296,6 +410,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( like ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_IN '(' value_expr_list ')' @@ -305,6 +425,12 @@ value_expr: $$->nOperation = SWQ_IN; $$->PushSubExpression( $1 ); $$->ReverseSubExpressions(); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_IN '(' value_expr_list ')' @@ -318,6 +444,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( in ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_BETWEEN value_expr_non_logical SWQT_AND value_expr_non_logical @@ -327,6 +459,12 @@ value_expr: $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); $$->PushSubExpression( $5 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_NOT SWQT_BETWEEN value_expr_non_logical SWQT_AND value_expr_non_logical @@ -340,6 +478,12 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( between ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_IS SWQT_NULL @@ -347,6 +491,12 @@ value_expr: $$ = new swq_expr_node( SWQ_ISNULL ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( $1 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr SWQT_IS SWQT_NOT SWQT_NULL @@ -358,19 +508,37 @@ value_expr: $$ = new swq_expr_node( SWQ_NOT ); $$->field_type = SWQ_BOOLEAN; $$->PushSubExpression( isnull ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } value_expr_list: value_expr ',' value_expr_list { $$ = $3; - $3->PushSubExpression( $1 ); + $$->PushSubExpression( $1 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr { $$ = new swq_expr_node( SWQ_ARGUMENT_LIST ); /* temporary value */ $$->PushSubExpression( $1 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } identifier: @@ -461,6 +629,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_MULTIPLY ); $$->PushSubExpression( new swq_expr_node(-1) ); $$->PushSubExpression( $2 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } } @@ -469,6 +643,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_ADD ); $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr_non_logical '-' value_expr_non_logical @@ -476,6 +656,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_SUBTRACT ); $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr_non_logical '*' value_expr_non_logical @@ -483,6 +669,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_MULTIPLY ); $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr_non_logical '/' value_expr_non_logical @@ -490,6 +682,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_DIVIDE ); $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | value_expr_non_logical '%' value_expr_non_logical @@ -497,6 +695,12 @@ value_expr_non_logical: $$ = new swq_expr_node( SWQ_MODULUS ); $$->PushSubExpression( $1 ); $$->PushSubExpression( $3 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | identifier '(' value_expr_list ')' @@ -540,6 +744,12 @@ value_expr_non_logical: $$ = $5; $$->PushSubExpression( $3 ); $$->ReverseSubExpressions(); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } type_def: @@ -547,6 +757,12 @@ type_def: { $$ = new swq_expr_node( SWQ_CAST ); $$->PushSubExpression( $1 ); + if( $$->HasReachedMaxDepth() ) + { + yyerror (context, "Maximum expression depth reached"); + delete $$; + YYERROR; + } } | identifier '(' SWQT_INTEGER_NUMBER ')'