From 023a985bfc8a627b1e4ccff797fbc33e3d064d6c Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 14 Jan 2021 22:13:50 -0500 Subject: [PATCH] gcode_macro: Use deepcopy() on get_status() results If a get_status() method returns a mutable object (such as a list or dict) then it would be possible for a gcode command template to incorrectly alter the program's internal state. Perform a deepcopy() operation on all get_status() return results to avoid that. Signed-off-by: Kevin O'Connor --- klippy/extras/gcode_macro.py | 9 ++++----- klippy/extras/heaters.py | 4 ++-- klippy/extras/query_endstops.py | 2 +- klippy/extras/save_variables.py | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/klippy/extras/gcode_macro.py b/klippy/extras/gcode_macro.py index aae5f3bb..3121024e 100644 --- a/klippy/extras/gcode_macro.py +++ b/klippy/extras/gcode_macro.py @@ -1,9 +1,9 @@ # Add ability to define custom g-code macros # -# Copyright (C) 2018-2019 Kevin O'Connor +# Copyright (C) 2018-2021 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. -import traceback, logging, ast +import traceback, logging, ast, copy import jinja2 @@ -26,7 +26,7 @@ class GetStatusWrapper: raise KeyError(val) if self.eventtime is None: self.eventtime = self.printer.get_reactor().monotonic() - self.cache[sval] = res = dict(po.get_status(self.eventtime)) + self.cache[sval] = res = copy.deepcopy(po.get_status(self.eventtime)) return res def __contains__(self, val): try: @@ -157,9 +157,8 @@ class GCodeMacro: pdesc = "Renamed builtin of '%s'" % (self.alias,) self.gcode.register_command(self.rename_existing, prev_cmd, desc=pdesc) self.gcode.register_command(self.alias, self.cmd, desc=self.cmd_desc) - return dict(self.variables) def get_status(self, eventtime): - return dict(self.variables) + return self.variables cmd_SET_GCODE_VARIABLE_help = "Set the value of a G-Code macro variable" def cmd_SET_GCODE_VARIABLE(self, gcmd): variable = gcmd.get('VARIABLE') diff --git a/klippy/extras/heaters.py b/klippy/extras/heaters.py index 829e9759..92d56db9 100644 --- a/klippy/extras/heaters.py +++ b/klippy/extras/heaters.py @@ -284,8 +284,8 @@ class PrinterHeaters: "G-Code sensor id %s already registered" % (gcode_id,)) self.gcode_id_to_sensor[gcode_id] = psensor def get_status(self, eventtime): - return {'available_heaters': list(self.available_heaters), - 'available_sensors': list(self.available_sensors)} + return {'available_heaters': self.available_heaters, + 'available_sensors': self.available_sensors} def turn_off_all_heaters(self, print_time=0.): for heater in self.heaters.values(): heater.set_temp(0.) diff --git a/klippy/extras/query_endstops.py b/klippy/extras/query_endstops.py index 0bbb11c2..949e1585 100644 --- a/klippy/extras/query_endstops.py +++ b/klippy/extras/query_endstops.py @@ -8,7 +8,7 @@ class QueryEndstops: def __init__(self, config): self.printer = config.get_printer() self.endstops = [] - self.last_state = {} + self.last_state = [] # Register webhook if server is available webhooks = self.printer.lookup_object('webhooks') webhooks.register_endpoint( diff --git a/klippy/extras/save_variables.py b/klippy/extras/save_variables.py index 6c88e3cf..f15dbc11 100644 --- a/klippy/extras/save_variables.py +++ b/klippy/extras/save_variables.py @@ -57,7 +57,7 @@ class SaveVariables: gcmd.respond_info("Variable Saved") self.loadVariables() def get_status(self, eventtime): - return {'variables': dict(self.allVariables)} + return {'variables': self.allVariables} def load_config(config): return SaveVariables(config)