def mutate(self) -> None: all_patches = self._mutate() if "patches" not in all_patches: logger.debug(f"No patches found by {self.NAME}") return for file in all_patches["patches"]: original_txt = self.slither.source_code[file].encode("utf8") patched_txt = original_txt offset = 0 patches = all_patches["patches"][file] patches.sort(key=lambda x: x["start"]) if not all(patches[i]["end"] <= patches[i + 1]["end"] for i in range(len(patches) - 1)): logger.info( f"Impossible to generate patch; patches collisions: {patches}" ) continue for patch in patches: patched_txt, offset = apply_patch(patched_txt, patch, offset) diff = create_diff(self.slither, original_txt, patched_txt, file) if not diff: logger.info(f"Impossible to generate patch; empty {patches}") print(diff)
def detect(self): all_results = self._detect() results = [] # only keep valid result, and remove dupplicate [ results.append(r) for r in all_results if self.slither.valid_result(r) and r not in results ] if results: if self.logger: info = '\n' for idx, result in enumerate(results): if self.slither.triage_mode: info += '{}: '.format(idx) info += result['description'] info += 'Reference: {}'.format(self.WIKI) self._log(info) if self.slither.generate_patches: for result in results: try: self._format(self.slither, result) if not 'patches' in result: continue result['patches_diff'] = dict() for file in result['patches']: original_txt = self.slither.source_code[file].encode( 'utf8') patched_txt = original_txt offset = 0 patches = result['patches'][file] patches.sort(key=lambda x: x['start']) if not all(patches[i]['end'] <= patches[i + 1]['end'] for i in range(len(patches) - 1)): self._log( f'Impossible to generate patch; patches collisions: {patches}' ) continue for patch in patches: patched_txt, offset = apply_patch( patched_txt, patch, offset) diff = create_diff(self.slither, original_txt, patched_txt, file) if not diff: self._log( f'Impossible to generate patch; empty {result}' ) else: result['patches_diff'][file] = diff except FormatImpossible as e: self._log( f'\nImpossible to patch:\n\t{result["description"]}\t{e}' ) if results and self.slither.triage_mode: while True: indexes = input( 'Results to hide during next runs: "0,1,..." or "All" (enter to not hide results): ' .format(len(results))) if indexes == 'All': self.slither.save_results_to_hide(results) return [] if indexes == '': return results if indexes.startswith('['): indexes = indexes[1:] if indexes.endswith(']'): indexes = indexes[:-1] try: indexes = [int(i) for i in indexes.split(',')] self.slither.save_results_to_hide([ r for (idx, r) in enumerate(results) if idx in indexes ]) return [ r for (idx, r) in enumerate(results) if idx not in indexes ] except ValueError: self.logger.error( yellow( 'Malformed input. Example of valid input: 0,1,2,3') ) return results
def detect(self): all_results = self._detect() # Keep only dictionaries all_results = [r.data for r in all_results] results = [] # only keep valid result, and remove dupplicate # pylint: disable=expression-not-assigned [ results.append(r) for r in all_results if self.slither.valid_result(r) and r not in results ] if results: if self.logger: info = "\n" for idx, result in enumerate(results): if self.slither.triage_mode: info += "{}: ".format(idx) info += result["description"] info += "Reference: {}".format(self.WIKI) self._log(info) if self.slither.generate_patches: for result in results: try: self._format(self.slither, result) if not "patches" in result: continue result["patches_diff"] = dict() for file in result["patches"]: original_txt = self.slither.source_code[file].encode( "utf8") patched_txt = original_txt offset = 0 patches = result["patches"][file] patches.sort(key=lambda x: x["start"]) if not all(patches[i]["end"] <= patches[i + 1]["end"] for i in range(len(patches) - 1)): self._log( f"Impossible to generate patch; patches collisions: {patches}" ) continue for patch in patches: patched_txt, offset = apply_patch( patched_txt, patch, offset) diff = create_diff(self.slither, original_txt, patched_txt, file) if not diff: self._log( f"Impossible to generate patch; empty {result}" ) else: result["patches_diff"][file] = diff except FormatImpossible as exception: self._log( f'\nImpossible to patch:\n\t{result["description"]}\t{exception}' ) if results and self.slither.triage_mode: while True: indexes = input( 'Results to hide during next runs: "0,1,...,{}" or "All" (enter to not hide results): ' .format(len(results))) if indexes == "All": self.slither.save_results_to_hide(results) return [] if indexes == "": return results if indexes.startswith("["): indexes = indexes[1:] if indexes.endswith("]"): indexes = indexes[:-1] try: indexes = [int(i) for i in indexes.split(",")] self.slither.save_results_to_hide([ r for (idx, r) in enumerate(results) if idx in indexes ]) return [ r for (idx, r) in enumerate(results) if idx not in indexes ] except ValueError: self.logger.error( yellow( "Malformed input. Example of valid input: 0,1,2,3") ) return results
def detect(self) -> List[Dict]: results: List[Dict] = [] # only keep valid result, and remove dupplicate # Keep only dictionaries for r in [output.data for output in self._detect()]: if self.compilation_unit.core.valid_result(r) and r not in results: results.append(r) if results and self.logger: self._log_result(results) if self.compilation_unit.core.generate_patches: for result in results: try: self._format(self.compilation_unit, result) if not "patches" in result: continue result["patches_diff"] = {} for file in result["patches"]: original_txt = self.compilation_unit.core.source_code[ file].encode("utf8") patched_txt = original_txt offset = 0 patches = result["patches"][file] patches.sort(key=lambda x: x["start"]) if not all(patches[i]["end"] <= patches[i + 1]["end"] for i in range(len(patches) - 1)): self._log( f"Impossible to generate patch; patches collisions: {patches}" ) continue for patch in patches: patched_txt, offset = apply_patch( patched_txt, patch, offset) diff = create_diff(self.compilation_unit, original_txt, patched_txt, file) if not diff: self._log( f"Impossible to generate patch; empty {result}" ) else: result["patches_diff"][file] = diff except FormatImpossible as exception: self._log( f'\nImpossible to patch:\n\t{result["description"]}\t{exception}' ) if results and self.slither.triage_mode: while True: indexes = input( f'Results to hide during next runs: "0,1,...,{len(results)}" or "All" (enter to not hide results): ' ) if indexes == "All": self.slither.save_results_to_hide(results) return [] if indexes == "": return results if indexes.startswith("["): indexes = indexes[1:] if indexes.endswith("]"): indexes = indexes[:-1] try: indexes_converted = [int(i) for i in indexes.split(",")] self.slither.save_results_to_hide([ r for (idx, r) in enumerate(results) if idx in indexes_converted ]) return [ r for (idx, r) in enumerate(results) if idx not in indexes_converted ] except ValueError: self.logger.error( yellow( "Malformed input. Example of valid input: 0,1,2,3") ) results = sorted(results, key=lambda x: x["id"]) return results