From b5e24edc60e3d80766082e464104e67ec5761057 Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Thu, 19 Feb 2026 08:33:01 +0100 Subject: [PATCH 1/4] Mark security issues as safe for security checks --- mergin/merginproject.py | 4 ++-- mergin/test/test_client.py | 18 +++--------------- mergin/utils.py | 6 +++--- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/mergin/merginproject.py b/mergin/merginproject.py index e5e771c..ffd10dd 100644 --- a/mergin/merginproject.py +++ b/mergin/merginproject.py @@ -330,8 +330,8 @@ def compare_file_sets(self, origin, current): :Example: - >>> origin = [{'checksum': '08b0e8caddafe74bf5c11a45f65cedf974210fed', 'path': 'base.gpkg', 'size': 2793, 'mtime': '2019-08-26T11:08:34.051221+02:00'}] - >>> current = [{'checksum': 'c9a4fd2afd513a97aba19d450396a4c9df8b2ba4', 'path': 'test.qgs', 'size': 31980, 'mtime': '2019-08-26T11:09:30.051221+02:00'}] + >>> origin = [{'checksum': '08b0e8caddafe74bf5c11a45f65cedf974210fed', 'path': 'base.gpkg', 'size': 2793, 'mtime': '2019-08-26T11:08:34.051221+02:00'}] # pragma: allowlist secret + >>> current = [{'checksum': 'c9a4fd2afd513a97aba19d450396a4c9df8b2ba4', 'path': 'test.qgs', 'size': 31980, 'mtime': '2019-08-26T11:09:30.051221+02:00'}] # pragma: allowlist secret >>> self.compare_file_sets(origin, current) {"added": [{'checksum': 'c9a4fd2afd513a97aba19d450396a4c9df8b2ba4', 'path': 'test.qgs', 'size': 31980, 'mtime': '2019-08-26T11:09:30.051221+02:00'}], "removed": [[{'checksum': '08b0e8caddafe74bf5c11a45f65cedf974210fed', 'path': 'base.gpkg', 'size': 2793, 'mtime': '2019-08-26T11:08:34.051221+02:00'}]], "renamed": [], "updated": []} diff --git a/mergin/test/test_client.py b/mergin/test/test_client.py index 0b86ec3..e85b198 100644 --- a/mergin/test/test_client.py +++ b/mergin/test/test_client.py @@ -10,10 +10,8 @@ import pytest import pytz import sqlite3 -import glob -from unittest.mock import patch, Mock +from unittest.mock import patch -from unittest.mock import patch, Mock from .. import InvalidProject from ..client import ( @@ -1382,16 +1380,6 @@ def _create_spatial_table(db_file): cursor.execute("COMMIT;") -def _delete_spatial_table(db_file): - """Drops spatial table called 'test' in sqlite database. Useful to simulate change of database schema.""" - con = sqlite3.connect(db_file) - cursor = con.cursor() - cursor.execute("DROP TABLE poi;") - cursor.execute("DELETE FROM gpkg_geometry_columns WHERE table_name='poi';") - cursor.execute("DELETE FROM gpkg_contents WHERE table_name='poi';") - cursor.execute("COMMIT;") - - def _check_test_table(db_file): """Checks whether the 'test' table exists and has one row - otherwise fails with an exception.""" assert _get_table_row_count(db_file, "test") == 1 @@ -1401,7 +1389,7 @@ def _get_table_row_count(db_file, table): try: con_verify = sqlite3.connect(db_file) cursor_verify = con_verify.cursor() - cursor_verify.execute("select count(*) from {};".format(table)) + cursor_verify.execute("select count(*) from {};".format(table)) # nosec B608 return cursor_verify.fetchone()[0] finally: cursor_verify.close() @@ -3097,7 +3085,7 @@ def test_uploaded_chunks_cache(mc): with open(file, "rb") as file_handle: data = file_handle.read() - checksum = hashlib.sha1() + checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ checksum.update(data) checksum_str = checksum.hexdigest() resp = mc.post(f"/v2/projects/{mp.project_id()}/chunks", data, {"Content-Type": "application/octet-stream"}) diff --git a/mergin/utils.py b/mergin/utils.py index 9e7be5e..418ecd8 100644 --- a/mergin/utils.py +++ b/mergin/utils.py @@ -9,7 +9,7 @@ import tempfile from enum import Enum from typing import Optional, Type, Union, ByteString -from .common import ClientError, WorkspaceRole +from .common import ClientError def generate_checksum(file, chunk_size=4096): @@ -20,7 +20,7 @@ def generate_checksum(file, chunk_size=4096): :param chunk_size: size of chunk :return: sha1 checksum """ - checksum = hashlib.sha1() + checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ with open(file, "rb") as f: while True: chunk = f.read(chunk_size) @@ -306,7 +306,7 @@ def get_data_checksum(data: ByteString) -> str: :param data: data to calculate checksum :return: sha1 checksum """ - checksum = hashlib.sha1() + checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ checksum.update(data) return checksum.hexdigest() From a368b50b71037c55d57be8cdbc1babc78dd8a9e8 Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Thu, 19 Feb 2026 08:39:31 +0100 Subject: [PATCH 2/4] explain nosec --- mergin/test/test_client.py | 4 ++-- mergin/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mergin/test/test_client.py b/mergin/test/test_client.py index e85b198..3a95edf 100644 --- a/mergin/test/test_client.py +++ b/mergin/test/test_client.py @@ -1389,7 +1389,7 @@ def _get_table_row_count(db_file, table): try: con_verify = sqlite3.connect(db_file) cursor_verify = con_verify.cursor() - cursor_verify.execute("select count(*) from {};".format(table)) # nosec B608 + cursor_verify.execute("select count(*) from {};".format(table)) # nosec B608 - internal test helper, not using user input return cursor_verify.fetchone()[0] finally: cursor_verify.close() @@ -3085,7 +3085,7 @@ def test_uploaded_chunks_cache(mc): with open(file, "rb") as file_handle: data = file_handle.read() - checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ + checksum = hashlib.sha1() # nosec B324 - usedforsecurity=False flag is compatible with python 3.9+ checksum.update(data) checksum_str = checksum.hexdigest() resp = mc.post(f"/v2/projects/{mp.project_id()}/chunks", data, {"Content-Type": "application/octet-stream"}) diff --git a/mergin/utils.py b/mergin/utils.py index 418ecd8..91796f3 100644 --- a/mergin/utils.py +++ b/mergin/utils.py @@ -20,7 +20,7 @@ def generate_checksum(file, chunk_size=4096): :param chunk_size: size of chunk :return: sha1 checksum """ - checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ + checksum = hashlib.sha1() # nosec B324 - usedforsecurity=False flag is compatible with python 3.9+ with open(file, "rb") as f: while True: chunk = f.read(chunk_size) @@ -306,7 +306,7 @@ def get_data_checksum(data: ByteString) -> str: :param data: data to calculate checksum :return: sha1 checksum """ - checksum = hashlib.sha1() # nosec B324 # usedforsecurity=False flag is compatible with python 3.9+ + checksum = hashlib.sha1() # nosec B324 - usedforsecurity=False flag is compatible with python 3.9+ checksum.update(data) return checksum.hexdigest() From 2cab67a25b079a98fe03da8d2eed759c11e12e7f Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Thu, 19 Feb 2026 08:40:55 +0100 Subject: [PATCH 3/4] black --- mergin/test/test_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mergin/test/test_client.py b/mergin/test/test_client.py index 3a95edf..799ebaf 100644 --- a/mergin/test/test_client.py +++ b/mergin/test/test_client.py @@ -1389,7 +1389,9 @@ def _get_table_row_count(db_file, table): try: con_verify = sqlite3.connect(db_file) cursor_verify = con_verify.cursor() - cursor_verify.execute("select count(*) from {};".format(table)) # nosec B608 - internal test helper, not using user input + cursor_verify.execute( + "select count(*) from {};".format(table) + ) # nosec B608 - internal test helper, not using user input return cursor_verify.fetchone()[0] finally: cursor_verify.close() From c2381312e20e584f522ce381cdd1f335ff6c0c1a Mon Sep 17 00:00:00 2001 From: Herman Snevajs Date: Thu, 19 Feb 2026 09:31:21 +0100 Subject: [PATCH 4/4] Checks don't run on tests --- mergin/test/test_client.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mergin/test/test_client.py b/mergin/test/test_client.py index 799ebaf..a19745a 100644 --- a/mergin/test/test_client.py +++ b/mergin/test/test_client.py @@ -1389,9 +1389,7 @@ def _get_table_row_count(db_file, table): try: con_verify = sqlite3.connect(db_file) cursor_verify = con_verify.cursor() - cursor_verify.execute( - "select count(*) from {};".format(table) - ) # nosec B608 - internal test helper, not using user input + cursor_verify.execute("select count(*) from {};".format(table)) return cursor_verify.fetchone()[0] finally: cursor_verify.close() @@ -3087,7 +3085,7 @@ def test_uploaded_chunks_cache(mc): with open(file, "rb") as file_handle: data = file_handle.read() - checksum = hashlib.sha1() # nosec B324 - usedforsecurity=False flag is compatible with python 3.9+ + checksum = hashlib.sha1() checksum.update(data) checksum_str = checksum.hexdigest() resp = mc.post(f"/v2/projects/{mp.project_id()}/chunks", data, {"Content-Type": "application/octet-stream"})