From 4c691f38960f49f0a4e6110fcad8165007e7fa47 Mon Sep 17 00:00:00 2001 From: marina-p Date: Fri, 2 Sep 2022 13:27:15 -0700 Subject: [PATCH] Fix #621 (#624) The checker was using the request definition of the last request. This did not correspond to the current rendering, which may have a different schema. The fix is to save the last rendered schema for use by checkers. Testing: demo_server test --- restler/checkers/invalid_value_checker.py | 16 ++++++++-------- restler/engine/core/requests.py | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/restler/checkers/invalid_value_checker.py b/restler/checkers/invalid_value_checker.py index 4289a06..a6c4c61 100644 --- a/restler/checkers/invalid_value_checker.py +++ b/restler/checkers/invalid_value_checker.py @@ -203,12 +203,13 @@ class InvalidValueChecker(CheckerBase): self._sequence = rendered_sequence.sequence last_request = self._sequence.last_request generation = self._sequence.length - + (last_rendered_schema_request,_) = self._sequence.last_request._last_rendered_schema_request self._checker_log.checker_print(f"Testing request: {last_request.endpoint} {last_request.method}") - # Note: this hash must be the hex definition, so each of the different schema variations of the request + # Note: this hash should be the last rendered schema hex definition, + # so each of the different schema variations of the request # are fuzzed separately (since they may contain different parameters). - request_hash = last_request.hex_definition + request_hash = last_rendered_schema_request.hex_definition if InvalidValueChecker.generation_executed_requests.get(generation) is None: # This is the first time this checker has seen this generation, create empty set of requests InvalidValueChecker.generation_executed_requests[generation] = set() @@ -229,7 +230,7 @@ class InvalidValueChecker(CheckerBase): req_primitive_type = req_block[0] return "_fuzzable_" in req_primitive_type or "_custom_" in req_primitive_type - fuzzable_parameter_value_blocks = list(map(lambda x : should_fuzz(x), last_request.definition)) + fuzzable_parameter_value_blocks = list(map(lambda x : should_fuzz(x), last_rendered_schema_request.definition)) num_fuzzable_blocks = len(list(filter(lambda x: x, fuzzable_parameter_value_blocks))) if num_fuzzable_blocks == 0: return @@ -266,13 +267,12 @@ class InvalidValueChecker(CheckerBase): self._checker_log.checker_print(f"Budget: {param_budget} values per parameter.") - for idx, is_fuzzable in enumerate(fuzzable_parameter_value_blocks): if not is_fuzzable: continue # Save the original request block. - request_block = last_request.definition[idx] + request_block = last_rendered_schema_request.definition[idx] primitive_type = request_block[0] # Create a request with this block being the only part of its definition, and get the @@ -294,7 +294,6 @@ class InvalidValueChecker(CheckerBase): logged_param = "" if field_name is None else f", name: {field_name}" self._checker_log.checker_print(f"Fuzzing request block {idx}, type: {primitive_type}{logged_param}") - tv = get_test_values(param_budget, temp_req, self._custom_invalid_mutations, self._value_generators_file_path, random_seed=self._override_random_seed) @@ -306,8 +305,9 @@ class InvalidValueChecker(CheckerBase): for fuzzed_value in tv: rendered_values[idx] = fuzzed_value if not isinstance(fuzzed_value, str): - print("not as tring!") + print("not a string!") rendered_data = "".join(rendered_values) + self._checker_log.checker_print(f"+++payload: {rendered_data}.+++") # Check time budget if Monitor().remaining_time_budget <= 0: diff --git a/restler/engine/core/requests.py b/restler/engine/core/requests.py index c482e7c..458fc33 100644 --- a/restler/engine/core/requests.py +++ b/restler/engine/core/requests.py @@ -256,6 +256,7 @@ class Request(object): self._create_once_requests = [] self._tracked_parameters = {} self._rendered_values_cache = RenderedValuesCache() + self._last_rendered_schema_request = None # Check for empty request before assigning ids if self._definition: @@ -1132,6 +1133,10 @@ class Request(object): rendered_data = values else: rendered_data = "".join(values) + + # Save the schema for this combination. + self._last_rendered_schema_request = (req, is_example) + yield rendered_data, parser, tracked_parameter_values next_combination = next_combination + 1