Skip to content

Commit d533081

Browse files
committed
Fix upload size validation leaking versioned limit onto media files
The versioned-size check was not gated on is_versioned_file, so media files (which never have a diff) were also capped at the smaller versioned limit. Branch on file type, and test both limits together.
1 parent 661f72c commit d533081

2 files changed

Lines changed: 43 additions & 4 deletions

File tree

mergin/local_changes.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ def __post_init__(self):
8888
total_changes = len(upload_changes)
8989
oversize_changes = []
9090
for change in upload_changes:
91-
if not is_versioned_file(change.path) and change.size > MAX_UPLOAD_MEDIA_SIZE:
92-
oversize_changes.append(change)
93-
elif not change.diff and change.size > MAX_UPLOAD_VERSIONED_SIZE:
91+
if is_versioned_file(change.path):
92+
if not change.diff and change.size > MAX_UPLOAD_VERSIONED_SIZE:
93+
oversize_changes.append(change)
94+
elif change.size > MAX_UPLOAD_MEDIA_SIZE:
9495
oversize_changes.append(change)
9596
if oversize_changes:
9697
error = ChangesValidationError("Some files exceed the maximum upload size", oversize_changes)

mergin/test/test_local_changes.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def test_local_changes_post_init_validation_media():
151151
assert err.value.invalid_changes[0].size == LARGE_FILE_SIZE
152152

153153

154-
def test_local_changes_post_init_validation_gpgkg():
154+
def test_local_changes_post_init_validation_gpkg():
155155
"""Test the get_gpgk_upload_file method of LocalProjectChanges."""
156156
# Define constants
157157
SIZE_LIMIT_MB = 10
@@ -186,6 +186,44 @@ def test_local_changes_post_init_validation_gpgkg():
186186
assert err.value.invalid_changes[0].size == LARGE_FILE_SIZE
187187

188188

189+
def test_local_changes_post_init_validation_both_limits():
190+
"""
191+
Validate media and versioned size limits.
192+
"""
193+
VERSIONED_LIMIT = 5 * 1024 * 1024 # 5 MB
194+
MEDIA_LIMIT = 10 * 1024 * 1024 # 10 MB
195+
BETWEEN_SIZE = 7 * 1024 * 1024
196+
OVER_MEDIA_SIZE = 15 * 1024 * 1024
197+
OVER_VERSIONED_SIZE = 8 * 1024 * 1024
198+
199+
added = [
200+
# media file between the limits: valid, must NOT be flagged
201+
FileChange(path="between.jpg", checksum="a1", size=BETWEEN_SIZE, mtime=datetime.now()),
202+
# media file over the media limit: flagged
203+
FileChange(path="big.jpg", checksum="a2", size=OVER_MEDIA_SIZE, mtime=datetime.now()),
204+
]
205+
updated = [
206+
# versioned full upload over the versioned limit: flagged
207+
FileChange(path="big.gpkg", checksum="b1", size=OVER_VERSIONED_SIZE, mtime=datetime.now(), diff=None),
208+
# versioned upload over the versioned limit but sent as a diff: valid
209+
FileChange(
210+
path="diffed.gpkg",
211+
checksum="b2",
212+
size=OVER_VERSIONED_SIZE,
213+
mtime=datetime.now(),
214+
diff={"path": "diffed-diff.gpkg", "checksum": "d1", "size": 1024, "mtime": datetime.now()},
215+
),
216+
]
217+
218+
with patch("mergin.local_changes.MAX_UPLOAD_MEDIA_SIZE", MEDIA_LIMIT):
219+
with patch("mergin.local_changes.MAX_UPLOAD_VERSIONED_SIZE", VERSIONED_LIMIT):
220+
with pytest.raises(ChangesValidationError) as err:
221+
LocalProjectChanges(added=added, updated=updated)
222+
223+
flagged = {c.path for c in err.value.invalid_changes}
224+
assert flagged == {"big.jpg", "big.gpkg"}
225+
226+
189227
def test_local_changes_post_init():
190228
"""Test the __post_init__ method of LocalProjectChanges."""
191229
# Define constants

0 commit comments

Comments
 (0)