From 5e0e02dd7c1309708ddd901668328e4830abde3f Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Sun, 14 Jul 2024 22:21:43 +0200
Subject: [PATCH] On /todo POSTs, improve handling of malformed fill_for
 fields.

---
 plomtask/http.py | 17 +++++++++++++----
 tests/todos.py   |  4 ++++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/plomtask/http.py b/plomtask/http.py
index 0d58af3..fbe4856 100644
--- a/plomtask/http.py
+++ b/plomtask/http.py
@@ -576,7 +576,7 @@ class TaskHandler(BaseHTTPRequestHandler):
             day_comment = self._form_data.get_str('day_comment')
             make_type = self._form_data.get_str('make_type')
         except NotFoundException as e:
-            raise BadFormatException(e)
+            raise BadFormatException from e
         old_todos = self._form_data.get_all_int('todo_id')
         new_todos = self._form_data.get_all_int('new_todo')
         comments = self._form_data.get_all_str('comment')
@@ -613,7 +613,7 @@ class TaskHandler(BaseHTTPRequestHandler):
         """Update Todo and its children."""
         # pylint: disable=too-many-locals
         # pylint: disable=too-many-branches
-        # pylint: disable=too-many-branches
+        # pylint: disable=too-many-statements
         adopted_child_ids = self._form_data.get_all_int('adopt')
         processes_to_make_full = self._form_data.get_all_int('make_full')
         processes_to_make_empty = self._form_data.get_all_int('make_empty')
@@ -631,10 +631,19 @@ class TaskHandler(BaseHTTPRequestHandler):
         calendarize = len(self._form_data.get_all_str('calendarize')) > 0
         comment = self._form_data.get_str('comment', ignore_strict=True)
         for v in fill_fors.values():
+            target_id: int
+            for prefix in ['make_empty_', 'make_full_']:
+                if v.startswith(prefix):
+                    try:
+                        target_id = int(v[len(prefix):])
+                    except ValueError as e:
+                        msg = 'bad fill_for target: {v}'
+                        raise BadFormatException(msg) from e
+                    continue
             if v.startswith('make_empty_'):
-                processes_to_make_empty += [int(v[11:])]
+                processes_to_make_empty += [target_id]
             elif v.startswith('make_full_'):
-                processes_to_make_full += [int(v[10:])]
+                processes_to_make_full += [target_id]
             elif v != 'ignore':
                 adopted_child_ids += [int(v)]
         to_remove = []
diff --git a/tests/todos.py b/tests/todos.py
index c5c29d4..66c4ff3 100644
--- a/tests/todos.py
+++ b/tests/todos.py
@@ -253,6 +253,10 @@ class TestsWithServer(TestCaseWithServer):
         for name in ['adopt', 'effort', 'make_full', 'make_empty',
                      'conditions', 'disables', 'blockers', 'enables']:
             self.check_post({name: 'x'}, '/todo?id=1', 400, '/todo')
+        for prefix in ['make_empty_', 'make_full_']:
+            for suffix in ['', 'x', '1.1']:
+                self.check_post({'fill_for_1': f'{prefix}{suffix}'},
+                                '/todo?id=1', 400, '/todo')
         # test we cannot POST adoption of self or non-existing Todo
         self.check_post({'adopt': 1}, '/todo?id=1', 400)
         self.check_post({'adopt': 2}, '/todo?id=1', 404)
-- 
2.30.2