From f13e6b2a2bb145e3a24321e1b1c6f3add37567e4 Mon Sep 17 00:00:00 2001 From: melton-jason Date: Sun, 5 May 2024 16:03:49 -0500 Subject: [PATCH] Correctly truncat value fields for spauditlog entries Fixes #829 --- specifyweb/specify/auditlog.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/specifyweb/specify/auditlog.py b/specifyweb/specify/auditlog.py index 6d9edece8bd..938b7e26211 100644 --- a/specifyweb/specify/auditlog.py +++ b/specifyweb/specify/auditlog.py @@ -7,8 +7,7 @@ from django.db import connection from django.conf import settings -from specifyweb.specify.models import Spauditlog -from specifyweb.specify.models import Spauditlogfield +from specifyweb.specify.models import Spauditlog, Spauditlogfield from specifyweb.context.remote_prefs import get_remote_prefs, get_global_prefs from specifyweb.specify.models import datamodel @@ -18,6 +17,13 @@ from . import auditcodes +def truncate_str_to_bytes(string: str, bytes: int) -> str: + str_as_bytes = string.encode() + try: + return str_as_bytes[:bytes].decode() + except UnicodeDecodeError as err: + return str_as_bytes[:err.start].decode() + class AuditLog(object): _auditingFlds = None @@ -60,6 +66,8 @@ def insert(self, obj, agent, parent_record=None): return self._log(auditcodes.INSERT, obj, agent, parent_record) def remove(self, obj, agent, parent_record=None): + from specifyweb.specify.api import parse_uri + log_obj = self._log(auditcodes.REMOVE, obj, agent, parent_record) if log_obj is not None: for spfld in obj.specify_model.fields: @@ -114,11 +122,12 @@ def _log(self, action, obj, agent, parent_record): def _log_fld_update(self, vals, log, agent): agent_id = agent if isinstance(agent, int) else (agent and agent.id) newval = vals['new_value'] + max_value_length = 2**16 - 1 if newval is not None: - newval = str(vals['new_value'])[:(2**16 - 1)] + newval = truncate_str_to_bytes(str(vals['new_value']), max_value_length) oldval = vals['old_value'] if oldval is not None: - oldval = str(vals['old_value'])[:(2**16 - 1)] + oldval = truncate_str_to_bytes(str(vals['old_value']), max_value_length) return Spauditlogfield.objects.create( fieldname=vals['field_name'], newvalue=newval,