From 0fe66b042a0a24570bf8e6beab096269cbb84fcb Mon Sep 17 00:00:00 2001 From: shahramn Date: Thu, 3 Oct 2024 12:36:21 +0100 Subject: [PATCH] ECC-1927: GRIB: grid_second_order hanging when encoding fields with Infinite values (try 1) --- examples/F90/CMakeLists.txt | 1 + .../F90/grib_infinity_grid_second_order.f90 | 42 +++++++++++++++++++ .../F90/grib_infinity_grid_second_order.sh | 39 +++++++++++++++++ src/grib_scaling.cc | 6 +++ 4 files changed, 88 insertions(+) create mode 100644 examples/F90/grib_infinity_grid_second_order.f90 create mode 100755 examples/F90/grib_infinity_grid_second_order.sh diff --git a/examples/F90/CMakeLists.txt b/examples/F90/CMakeLists.txt index 7ec9c28b2..c98f234df 100644 --- a/examples/F90/CMakeLists.txt +++ b/examples/F90/CMakeLists.txt @@ -55,6 +55,7 @@ if( HAVE_BUILD_TOOLS ) grib_get_set_uuid grib_clone grib_ecc-1316 + grib_infinity_grid_second_order bufr_attributes bufr_clone bufr_expanded diff --git a/examples/F90/grib_infinity_grid_second_order.f90 b/examples/F90/grib_infinity_grid_second_order.f90 new file mode 100644 index 000000000..cfcd2e32a --- /dev/null +++ b/examples/F90/grib_infinity_grid_second_order.f90 @@ -0,0 +1,42 @@ +! (C) Copyright 2005- ECMWF. +! +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! +! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by +! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. +! +! Description: issue with grid_second_order hanging when encoding fields with infinite values +! +! +USE eccodes +USE ieee_arithmetic + +IMPLICIT NONE + +INTEGER :: IGRIBH +REAL(KIND=8) :: ZT (421*441) + +CHARACTER*32 :: CLPACKING ! grid_simple / grid_second_order +CHARACTER*32 :: CLINFINITY ! 0 / 1 + +CALL GETARG (1, CLPACKING) +CALL GETARG (2, CLINFINITY) + +CALL codes_grib_new_from_samples(IGRIBH, "regular_ll_sfc_grib2") +CALL codes_set_long (IGRIBH, "Ni", 421_8) +CALL codes_set_long (IGRIBH, "Nj", 441_8) +CALL codes_set_long (IGRIBH, "bitsPerValue", 16_8) +CALL codes_set_string (IGRIBH, "packingType", TRIM (CLPACKING)) + +ZT = 0._8 + +IF (CLINFINITY == '1') THEN + ZT (1) = IEEE_VALUE (0._8, IEEE_POSITIVE_INF) +ENDIF + +CALL codes_set_real8_array (IGRIBH, "values", ZT) +! write (*,*) 'status=',status +! write (*,*) 'ZT= ',ZT(1) + +END diff --git a/examples/F90/grib_infinity_grid_second_order.sh b/examples/F90/grib_infinity_grid_second_order.sh new file mode 100755 index 000000000..1da3c47b2 --- /dev/null +++ b/examples/F90/grib_infinity_grid_second_order.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# (C) Copyright 2005- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by +# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. +# + +. ./include.ctest.sh + +for encoding in grid_simple grid_second_order +do + + for infinity in 0 1 + do + + if [ $infinity -eq 1 ] + then + set +e + fi + + ${examples_dir}/eccodes_f_grib_infinity_grid_second_order $encoding $infinity + c=$? + + if [ $infinity -eq 1 ] + then + set -e + if [ $c -eq 0 ] + then + echo "Encoding infinite numbers should fail" + exit 1 + fi + fi + + done + +done diff --git a/src/grib_scaling.cc b/src/grib_scaling.cc index e49a1e6dc..c48e0159b 100644 --- a/src/grib_scaling.cc +++ b/src/grib_scaling.cc @@ -10,6 +10,7 @@ #include "grib_scaling.h" #include "grib_api_internal.h" +#include // Unfortunately, metkit uses grib_power() (illegal usage of private API) // As soon as it is fixed, the wrapper below can be deleted @@ -26,6 +27,11 @@ long grib_get_binary_scale_fact(double max, double min, long bpval, int* error) unsigned long maxint = 0; const size_t ulong_size = sizeof(maxint) * 8; + if ((isnan(range) || isinf(range))) { + *error = GRIB_OUT_OF_RANGE; /*overflow*/ + return 0; + } + /* See ECC-246 unsigned long maxint = codes_power(bpval,2) - 1; double dmaxint=(double)maxint;