Skip to content

Return the error instead of crashing when a netCDF grid header has a zero increment - #9266

Merged
Esteban82 merged 2 commits into
masterfrom
fix-9261
Oct 15, 2026
Merged

Esteban82 merged 2 commits into
masterfrom
fix-9261

Conversation

@Esteban82

Copy link
Copy Markdown
Member

A netCDF grid with one row and no y:actual_range (as GDAL writes it) is read with y range 0/0, and the read crashed because gmtnc_grd_prep_io only printed the error and went on. It now returns it, so the module stops with the usual read error.

Tested with:

gmt grdmath -R-1.2/1.2/-0.2/0.2 -I0.4 -r X = good.grd
gmt grdconvert good.grd bad.nc=gd:netCDF
gmt grdtrend bad.nc -N4+x -Tt.grd

Before: Grid y increment <= 0.0 and a segfault. After: the same message plus GMT_GRID_READ_ERROR, no crash. New test: test/gdal/gdal_1row_netcdf.sh.

Question

The message is the generic one GMT uses for read errors. Would a clearer one be better, e.g. "Grid bad.nc has a single row and no y actual_range attribute, so its y range and increment are unknown"?

Refs #9261 (the crash only).

Reviewed with Claude Opus 5.5. Written with Claude Sonnet 5.5.

@joa-quim

Copy link
Copy Markdown
Member

I think the generic message it's good enough. If we were to be specific that another one should be issued for bad column grids. But I emphasize, this failure on Windows start short time ago.

…d_prep_io

A netCDF grid with one row and no y:actual_range (as written by GDAL) is read
with y range 0/0, so y_inc is 0 and n_rows is 0. gmt_adjust_loose_wesn returns
that error, but gmtnc_grd_prep_io only printed it and went on, and the read
crashed (an assertion in gmtnc_pad_grid in Debug builds, a segfault in Release
builds). Return the error so the read fails instead.

gmt_nc_read_grd now passes the error code up unchanged instead of turning it
into GMT_RUNTIME_ERROR, which has no entry in gmt_error_string, so the caller
printed "(null)". The message is now the same kind as for other read errors:
"grdtrend (gmtapi_import_grid): Grid y increment <= 0.0 [file]".

Add a test that writes such a grid with GDAL. Fixes the crash reported in #9261.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Esteban82

Copy link
Copy Markdown
Member Author

I think the generic message it's good enough. If we were to be specific that another one should be issued for bad column grids. But I emphasize, this failure on Windows start short time ago.

Ok, I will not change the message.

@Esteban82

Copy link
Copy Markdown
Member Author

Updated the test in the last push. The previous version failed on the Windows CI: it wrote the 1-row grid with grdmath as netCDF and read it back with grdconvert, and on Windows that read already fails (the 1-row grid is read with y range 0/0, see #9261), so the test never got to the case it is meant to check. The 1-row input is now written in GMT's native binary format (=bf), so the only netCDF 1-row grid that is read is the one GDAL writes. The fix itself is unchanged.

@joa-quim

Copy link
Copy Markdown
Member

I am confused with this

grdmath -R-1.2/1.2/-0.2/0.2 -I0.4 -r X = row.nc=gd:netcdf
Warning 1: 1-pixel width/height files not supported, xdim: 6 ydim: 1
grdmath [ERROR]: Error adding history: -38

grdinfo row.nc

row.nc: Title: GDAL Band Number 1
row.nc: Command: Thu Oct 15 00:54:27 2026: GDAL CreateCopy( row.nc, ... )
row.nc: Remark:
row.nc: Pixel node registration used [Geographic grid]
row.nc: Grid file format: nf = GMT netCDF format (32-bit float), CF-1.7
row.nc: x_min: -1.2 x_max: 1.2 x_inc: 0.4 (24 min) name: longitude n_columns: 6
row.nc: y_min: 0 y_max: 0 y_inc: 0 name: latitude n_rows: 0
row.nc: v_min: 0 v_max: 0 name: GDAL Band Number 1

But

grdmath -R-1.2/1.2/-0.2/0.2 -I0.4 -r X = row.grd

grdinfo row.nc
row.nc: Title: GDAL Band Number 1
row.nc: Command: Thu Oct 15 00:54:27 2026: GDAL CreateCopy( row.nc, ... )
row.nc: Remark:
row.nc: Pixel node registration used [Geographic grid]
row.nc: Grid file format: nf = GMT netCDF format (32-bit float), CF-1.7
row.nc: x_min: -1.2 x_max: 1.2 x_inc: 0.4 (24 min) name: longitude n_columns: 6
row.nc: y_min: 0 y_max: 0 y_inc: 0 name: latitude n_rows: 0
row.nc: v_min: 0 v_max: 0 name: GDAL Band Number 1

The test times out on the macOS CI (480 s, three attempts) while it passes on
Linux and Windows. Keep only the fix.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Esteban82

Copy link
Copy Markdown
Member Author

In the second block grdinfo was run on row.nc again (the GDAL file from the first block), so it shows the same header; on row.grd it should be the valid 6x1 grid. The first block is the point of this PR: GDAL writes no y:actual_range for a 1-row netCDF, so GMT reads y 0/0, and it used to crash on it.

I removed the new test. Only the fix is left.

@Esteban82

Copy link
Copy Markdown
Member Author

Now the test trend_xy_plot.sh fails with an error message (as expected)

1/3 Test #644: test/grdtrend/trend_xy_plot.sh ........***Failed    2.82 sec
Set GMT_SESSION_NAME = 62933
grdtrend (gmtapi_import_grid): Grid y increment <= 0.0 [data.grd]
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
grd2xyz (gmtapi_import_grid): Grid y increment <= 0.0 [data.grd]
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
[Session gmt.exe (0)]: Error returned from GMT API: GMT_GRID_READ_ERROR (18)
...

@Esteban82
Esteban82 merged commit 11cc8ba into master Oct 15, 2026
17 of 18 checks passed
@Esteban82
Esteban82 deleted the fix-9261 branch October 15, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

add-changelog Add PR to the changelog bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants