From 44e008745d829201482c0dbb16b9491d9341b0ec Mon Sep 17 00:00:00 2001 From: frdel <38891707+frdel@users.noreply.github.com> Date: Mon, 30 Mar 2026 11:50:59 +0200 Subject: [PATCH] Sanitize print logs; refactor popular plugin logic Ensure printed output and HTML logs are safe by importing and applying sanitize_string, opening log files with utf-8 and errors='replace', and sanitizing text before writing. Add tests to verify lone surrogate characters are replaced and that logging won't crash on invalid Unicode. In the plugin installer UI, introduce POPULAR_PLUGIN_MIN_STARS and centralize popularity checking in _isPopularPlugin, using it for filtering and counts. --- helpers/print_style.py | 11 ++- .../webui/install-detail.html | 85 +++++++++++++++++++ .../webui/install-index.html | 29 +++++++ .../webui/pluginInstallStore.js | 36 +++++++- tests/test_print_style.py | 52 ++++++++++++ tools/skills_tool.py | 70 ++++++++++++++- 6 files changed, 272 insertions(+), 11 deletions(-) create mode 100644 tests/test_print_style.py diff --git a/helpers/print_style.py b/helpers/print_style.py index 88db30532..ab70f9469 100644 --- a/helpers/print_style.py +++ b/helpers/print_style.py @@ -3,6 +3,7 @@ import sys from datetime import datetime from collections.abc import Mapping from . import files +from .strings import sanitize_string _runtime_module = None @@ -34,7 +35,7 @@ class PrintStyle: os.makedirs(logs_dir, exist_ok=True) log_filename = datetime.now().strftime("log_%Y%m%d_%H%M%S.html") PrintStyle.log_file_path = os.path.join(logs_dir, log_filename) - with open(PrintStyle.log_file_path, "w") as f: + with open(PrintStyle.log_file_path, "w", encoding="utf-8", errors="replace") as f: f.write("
\n")
 
     def _get_rgb_color_code(self, color, is_background=False):
@@ -93,13 +94,13 @@ class PrintStyle:
             self.padding_added = True
 
     def _log_html(self, html):
-        with open(PrintStyle.log_file_path, "a", encoding='utf-8') as f: # type: ignore # add encoding='utf-8'
-            f.write(html)
+        with open(PrintStyle.log_file_path, "a", encoding="utf-8", errors="replace") as f:  # type: ignore[arg-type]
+            f.write(sanitize_string(html))
 
     @staticmethod
     def _close_html_log():
         if PrintStyle.log_file_path:
-            with open(PrintStyle.log_file_path, "a") as f:
+            with open(PrintStyle.log_file_path, "a", encoding="utf-8", errors="replace") as f:
                 f.write("
") @staticmethod @@ -145,6 +146,8 @@ class PrintStyle: # If masking fails, proceed without masking to avoid breaking functionality pass + text = sanitize_string(text) + return text, self._get_styled_text(text), self._get_html_styled_text(text) def print(self, *args, sep=' ', end='\n', flush=True): diff --git a/plugins/_plugin_installer/webui/install-detail.html b/plugins/_plugin_installer/webui/install-detail.html index 4cf5e55a4..6a42bc345 100644 --- a/plugins/_plugin_installer/webui/install-detail.html +++ b/plugins/_plugin_installer/webui/install-detail.html @@ -25,6 +25,12 @@

+ @@ -100,6 +106,17 @@
+ +
+