home · contact · privacy
In GET /process handler, catch malformed ?title_b64= params.
authorChristian Heller <c.heller@plomlompom.de>
Sat, 22 Jun 2024 02:49:29 +0000 (04:49 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sat, 22 Jun 2024 02:49:29 +0000 (04:49 +0200)
plomtask/http.py

index 0626b4c1e5aab5bd4bceb0d6594cbaa9da448ae8..b7040f76fa9c3c1d58b0ceedc58fabf02752f616 100644 (file)
@@ -3,6 +3,7 @@ from __future__ import annotations
 from dataclasses import dataclass
 from typing import Any, Callable
 from base64 import b64encode, b64decode
 from dataclasses import dataclass
 from typing import Any, Callable
 from base64 import b64encode, b64decode
+from binascii import Error as binascii_Exception
 from http.server import BaseHTTPRequestHandler
 from http.server import HTTPServer
 from urllib.parse import urlparse, parse_qs
 from http.server import BaseHTTPRequestHandler
 from http.server import HTTPServer
 from urllib.parse import urlparse, parse_qs
@@ -187,8 +188,8 @@ class TaskHandler(BaseHTTPRequestHandler):
         returns successfully, or right after any exception is triggered –
         otherwise, race conditions become plausible.
 
         returns successfully, or right after any exception is triggered –
         otherwise, race conditions become plausible.
 
-        Note that any POST attempt, even a failed one, may end in problematic
-        inconsistencies:
+        Note that otherwise any POST attempt, even a failed one, may end in
+        problematic inconsistencies:
 
         - if the POST handler experiences an Exception, changes to objects
           won't get written to the DB, but the changed objects may remain in
 
         - if the POST handler experiences an Exception, changes to objects
           won't get written to the DB, but the changed objects may remain in
@@ -225,8 +226,8 @@ class TaskHandler(BaseHTTPRequestHandler):
                     if hasattr(self, handler_name):
                         handler = getattr(self, handler_name)
                         redir_target = f(self, handler)
                     if hasattr(self, handler_name):
                         handler = getattr(self, handler_name)
                         redir_target = f(self, handler)
-                        if 'POST' != http_method:
-                           clear_caches()
+                        if 'POST' == http_method:
+                            clear_caches()
                         if redir_target:
                             self.send_response(302)
                             self.send_header('Location', redir_target)
                         if redir_target:
                             self.send_response(302)
                             self.send_header('Location', redir_target)
@@ -235,8 +236,8 @@ class TaskHandler(BaseHTTPRequestHandler):
                         msg = f'{not_found_msg}: {self._site}'
                         raise NotFoundException(msg)
                 except HandledException as error:
                         msg = f'{not_found_msg}: {self._site}'
                         raise NotFoundException(msg)
                 except HandledException as error:
-                    if 'POST' != http_method:
-                       clear_caches()
+                    if 'POST' == http_method:
+                        clear_caches()
                     ctx = {'msg': error}
                     self._send_page(ctx, 'msg', error.http_code)
                 finally:
                     ctx = {'msg': error}
                     self._send_page(ctx, 'msg', error.http_code)
                 finally:
@@ -475,13 +476,18 @@ class TaskHandler(BaseHTTPRequestHandler):
         owned_ids = self._params.get_all_int('has_step')
         title_64 = self._params.get_str('title_b64')
         if title_64:
         owned_ids = self._params.get_all_int('has_step')
         title_64 = self._params.get_str('title_b64')
         if title_64:
-            title = b64decode(title_64.encode()).decode()
+            try:
+                title = b64decode(title_64.encode()).decode()
+            except binascii_Exception as exc:
+                msg = 'invalid base64 for ?title_b64='
+                raise BadFormatException(msg) from exc
             process.title.set(title)
             process.title.set(title)
+        preset_top_step = None
         owners = process.used_as_step_by(self.conn)
         for step_id in owner_ids:
             owners += [Process.by_id(self.conn, step_id)]
         owners = process.used_as_step_by(self.conn)
         for step_id in owner_ids:
             owners += [Process.by_id(self.conn, step_id)]
-        preset_top_step = None
         for process_id in owned_ids:
         for process_id in owned_ids:
+            Process.by_id(self.conn, process_id)  # to ensure ID exists
             preset_top_step = process_id
         return {'process': process, 'is_new': process.id_ is None,
                 'preset_top_step': preset_top_step,
             preset_top_step = process_id
         return {'process': process, 'is_new': process.id_ is None,
                 'preset_top_step': preset_top_step,