diff --git a/bento_lib/search/data_structure.py b/bento_lib/search/data_structure.py index 0f71d55..6fdbbbc 100644 --- a/bento_lib/search/data_structure.py +++ b/bento_lib/search/data_structure.py @@ -129,9 +129,10 @@ def evaluate( internal: bool = False, resolve_checks: bool = True, check_permissions: bool = True, + secure_errors: bool = True, ): # The validate flag is used to avoid redundantly validating the integrity of child data structures - _validate_data_structure_against_schema(data_structure, schema) + _validate_data_structure_against_schema(data_structure, schema, secure_errors=secure_errors) return evaluate_no_validate(ast, data_structure, schema, index_combination, internal, resolve_checks, check_permissions) @@ -237,6 +238,7 @@ def check_ast_against_data_structure( schema: JSONSchema, internal: bool = False, return_all_index_combinations: bool = False, + secure_errors: bool = True, ) -> Union[bool, Iterable[IndexCombination]]: """ Checks a query against a data structure, returning True if the @@ -245,13 +247,14 @@ def check_ast_against_data_structure( :param schema: A JSON schema representing valid data objects. :param internal: Whether internal-only fields are allowed to be resolved. :param return_all_index_combinations: Whether internal-only fields are allowed to be resolved. + :param secure_errors: Whether to not expose any data in error messaevaluateges. Impairs debugging. :return: Determined by return_all_index_combinations; either 1) A boolean representing whether or not the query matches the data object; or 2) An iterable of all index combinations where the query matches the data object """ # Validate data structure against JSON schema here to avoid having to repetitively do it later - _validate_data_structure_against_schema(data_structure, schema) + _validate_data_structure_against_schema(data_structure, schema, secure_errors=secure_errors) # Collect all array resolves and their lengths in order to properly cross-product arrays array_lengths = _collect_array_lengths(ast, data_structure, schema, True) diff --git a/tests/test_search.py b/tests/test_search.py index 2bf0b40..92ef559 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -832,11 +832,17 @@ def test_postgres_invalid_expressions(): # noinspection PyProtectedMember def test_data_structure_search(): for e, i, v, ic in DS_VALID_EXPRESSIONS: - assert data_structure.evaluate(queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic) == v + assert data_structure.evaluate( + queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic, secure_errors=False) == v + assert data_structure.evaluate( + queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic, secure_errors=True) == v for q, i, v, _ni, nm in DS_VALID_QUERIES: assert data_structure.check_ast_against_data_structure(queries.convert_query_to_ast(q), TEST_DATA_1, - TEST_SCHEMA, i) == v + TEST_SCHEMA, i, secure_errors=False) == v + + assert data_structure.check_ast_against_data_structure(queries.convert_query_to_ast(q), TEST_DATA_1, + TEST_SCHEMA, i, secure_errors=True) == v ics = tuple(data_structure.check_ast_against_data_structure( queries.convert_query_to_ast(q), TEST_DATA_1, TEST_SCHEMA, i, return_all_index_combinations=True)) @@ -852,11 +858,21 @@ def test_data_structure_search(): for e, i, ex, ic in DS_INVALID_EXPRESSIONS: with raises(ex): - data_structure.evaluate(queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic, i) + data_structure.evaluate( + queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic, i, secure_errors=False) + with raises(ex): + data_structure.evaluate( + queries.convert_query_to_ast(e), TEST_DATA_1, TEST_SCHEMA, ic, i, secure_errors=True) # Invalid data + + with raises(ValueError): + data_structure.evaluate( + queries.convert_query_to_ast(TEST_EXPR_1), INVALID_DATA, TEST_SCHEMA, {}, secure_errors=False) + with raises(ValueError): - data_structure.evaluate(queries.convert_query_to_ast(TEST_EXPR_1), INVALID_DATA, TEST_SCHEMA, {}) + data_structure.evaluate( + queries.convert_query_to_ast(TEST_EXPR_1), INVALID_DATA, TEST_SCHEMA, {}, secure_errors=True) def test_large_data_structure_query(): @@ -866,7 +882,7 @@ def large_query(): # Test large query import cProfile - cProfile.runctx("large_query()", None, locals(), sort="tottime") + cProfile.runctx("large_query()", {}, locals(), sort="tottime") # noinspection PyProtectedMember