From 17644d4205611d473f227636d978e216f408e599 Mon Sep 17 00:00:00 2001 From: "Sardar Nanakjoth Singh (WIPRO LIMITED)" Date: Thu, 3 Jul 2025 15:59:44 +0530 Subject: [PATCH 1/2] Add grid size check for corrupted .grd files (#451) --- harmonica/_io/oasis_montaj_grd.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/harmonica/_io/oasis_montaj_grd.py b/harmonica/_io/oasis_montaj_grd.py index 80eb2f067..b9f7c65ce 100644 --- a/harmonica/_io/oasis_montaj_grd.py +++ b/harmonica/_io/oasis_montaj_grd.py @@ -107,6 +107,14 @@ def load_oasis_montaj_grid(fname): order = "F" shape = (header["shape_e"], header["shape_v"]) spacing = (header["spacing_e"], header["spacing_v"]) + # Check that the number of elements matches the expected shape + expected_size = shape[0] * shape[1] + actual_size = grid.size + if actual_size != expected_size: + raise ValueError( + f"Grid data size mismatch: found {actual_size} elements, expected {expected_size} (shape {shape}). " + "The file may be corrupted or incomplete." + ) grid = grid.reshape(shape, order=order) # Build coords if header["rotation"] == 0: From 6b81daa30a89f1b17551e014a2596c8e5b8e09b3 Mon Sep 17 00:00:00 2001 From: "Sardar Nanakjoth Singh (WIPRO LIMITED)" Date: Fri, 18 Jul 2025 11:33:06 +0530 Subject: [PATCH 2/2] Add test for corrupted GRD file and sample incomplete_grid.grd (#451) --- harmonica/_io/oasis_montaj_grd.py | 8 ++++++++ harmonica/tests/data/incomplete_grid.grd | Bin 0 -> 10212 bytes harmonica/tests/test_oasis.py | 6 ++++++ 3 files changed, 14 insertions(+) create mode 100644 harmonica/tests/data/incomplete_grid.grd diff --git a/harmonica/_io/oasis_montaj_grd.py b/harmonica/_io/oasis_montaj_grd.py index 80eb2f067..b9f7c65ce 100644 --- a/harmonica/_io/oasis_montaj_grd.py +++ b/harmonica/_io/oasis_montaj_grd.py @@ -107,6 +107,14 @@ def load_oasis_montaj_grid(fname): order = "F" shape = (header["shape_e"], header["shape_v"]) spacing = (header["spacing_e"], header["spacing_v"]) + # Check that the number of elements matches the expected shape + expected_size = shape[0] * shape[1] + actual_size = grid.size + if actual_size != expected_size: + raise ValueError( + f"Grid data size mismatch: found {actual_size} elements, expected {expected_size} (shape {shape}). " + "The file may be corrupted or incomplete." + ) grid = grid.reshape(shape, order=order) # Build coords if header["rotation"] == 0: diff --git a/harmonica/tests/data/incomplete_grid.grd b/harmonica/tests/data/incomplete_grid.grd new file mode 100644 index 0000000000000000000000000000000000000000..531ecc0e58b6159ce3e74913245ae997264e7833 GIT binary patch literal 10212 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 V2vPer$k}H~EE!oXXnHh&{Xh2BH?sf$ literal 0 HcmV?d00001 diff --git a/harmonica/tests/test_oasis.py b/harmonica/tests/test_oasis.py index b1193acfe..041ed87e7 100644 --- a/harmonica/tests/test_oasis.py +++ b/harmonica/tests/test_oasis.py @@ -107,3 +107,9 @@ def test_rotated_grid(self): npt.assert_allclose( grid.rotation, np.degrees(np.arctan((north - south) / (east - west))) ) + + +def test_incomplete_grid_raises_error(): + corrupted_file = "harmonica/tests/data/incomplete_grid.grd" + with pytest.raises(ValueError, match="Grid data size mismatch"): + load_oasis_montaj_grid(corrupted_file)