ECC-750: BUFR encoding: maximum allowed value

This commit is contained in:
Shahram Najm 2018-09-13 16:43:53 +01:00
parent 5c51da7e28
commit ac9a60435f
3 changed files with 104 additions and 4 deletions

View File

@ -702,6 +702,19 @@ static void set_missing_long_to_double(grib_darray* dvalues)
} }
} }
/* ECC-750: The 'factor' argument is 10^-scale */
static int descriptor_get_min_max(bufr_descriptor* bd, long width, long reference, double factor,
double* minAllowed, double* maxAllowed)
{
/* Maximum value is allowed to be the largest number (all bits 1) which means it's MISSING */
unsigned long max1 = (1UL << width) - 1; /* Highest value for number with 'width' bits */
DebugAssert(width > 0 && width <= 32);
*maxAllowed = (max1 + reference) * factor;
*minAllowed = reference * factor;
return GRIB_SUCCESS;
}
static int encode_double_array(grib_context* c,grib_buffer* buff,long* pos, bufr_descriptor* bd, static int encode_double_array(grib_context* c,grib_buffer* buff,long* pos, bufr_descriptor* bd,
grib_accessor_bufr_data_array* self,grib_darray* dvalues) grib_accessor_bufr_data_array* self,grib_darray* dvalues)
{ {
@ -731,8 +744,7 @@ static int encode_double_array(grib_context* c,grib_buffer* buff,long* pos, bufr
inverseFactor= grib_power(bd->scale,10); inverseFactor= grib_power(bd->scale,10);
modifiedWidth= bd->width; modifiedWidth= bd->width;
maxAllowed=(grib_power(modifiedWidth,2)+modifiedReference)*modifiedFactor; descriptor_get_min_max(bd, modifiedWidth, modifiedReference, modifiedFactor, &minAllowed, &maxAllowed);
minAllowed=modifiedReference*modifiedFactor;
nvals=grib_iarray_used_size(self->iss_list); nvals=grib_iarray_used_size(self->iss_list);
if (nvals<=0) return GRIB_NO_VALUES; if (nvals<=0) return GRIB_NO_VALUES;
@ -903,8 +915,8 @@ static int encode_double_value(grib_context* c,grib_buffer* buff,long* pos,bufr_
modifiedReference= bd->reference; modifiedReference= bd->reference;
modifiedFactor= bd->factor; modifiedFactor= bd->factor;
modifiedWidth= bd->width; modifiedWidth= bd->width;
maxAllowed=(grib_power(modifiedWidth,2)+modifiedReference)*modifiedFactor;
minAllowed=modifiedReference*modifiedFactor; descriptor_get_min_max(bd, modifiedWidth, modifiedReference, modifiedFactor, &minAllowed, &maxAllowed);
grib_buffer_set_ulength_bits(c,buff,buff->ulength_bits+modifiedWidth); grib_buffer_set_ulength_bits(c,buff,buff->ulength_bits+modifiedWidth);
if (value==GRIB_MISSING_DOUBLE) { if (value==GRIB_MISSING_DOUBLE) {

View File

@ -88,6 +88,7 @@ list( APPEND tests_data_reqd
bufr_ecc-379 bufr_ecc-379
bufr_ecc-393 bufr_ecc-393
bufr_ecc-433 bufr_ecc-433
bufr_ecc-750
grib_ecc-490 grib_ecc-490
bufr_ecc-556 bufr_ecc-556
gts_get gts_get

87
tests/bufr_ecc-750.sh Executable file
View File

@ -0,0 +1,87 @@
#!/bin/sh
# Copyright 2005-2018 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.sh
# ---------------------------------------------------------
# This is the test for the JIRA issue ECC-750.
# Encoding values which exceed the maximum allowed
# ---------------------------------------------------------
label="bufr_ecc-750-test"
tempRules=temp.${label}.filter
tempBufr=temp.${label}.bufr
# --------------------------------
# Case 1: airTemperature, width=12
# --------------------------------
input=${data_dir}/bufr/temp_101.bufr
cat > $tempRules <<EOF
set unpack=1;
set #1#airTemperature=409.6; # max=409.5
set pack=1;
write;
EOF
# Should fail
set +e
${tools_dir}/codes_bufr_filter -o $tempBufr $tempRules $input
status=$?
set -e
[ $status -ne 0 ]
# Test for MISSING
echo 'set unpack=1; set #3#airTemperature=409.5; set pack=1; write;' | ${tools_dir}/codes_bufr_filter -o $tempBufr - $input
temperature=`${tools_dir}/bufr_get -s unpack=1 -p '#3#airTemperature' $tempBufr`
[ "$temperature" = "MISSING" ]
# ---------------------------------
# Case 2: inputDataPresentIndicator
# ---------------------------------
input=${data_dir}/bufr/amv2_87.bufr
cat > $tempRules <<EOF
set inputDataPresentIndicator= {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 0, 0, 0, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1};
set unexpandedDescriptors={
310195, 222000, 236000, 101103, 31031, 1031, 1032, 101004, 33007, 222000,
237000, 1031, 1032, 101004, 33252, 222000, 237000, 1031, 1032, 101004,
33253, 222000, 237000, 1031, 1032, 101004, 33007, 222000, 237000, 1031,
1032, 101004, 33252, 222000, 237000, 1031, 1032, 101004, 33253, 222000,
237000, 1031, 1032, 101004, 33007, 222000, 237000, 1031, 1032, 101004,
33252, 222000, 237000, 1031, 1032, 101004, 33253 };
EOF
# Should fail
set +e
${tools_dir}/codes_bufr_filter $tempRules $input
status=$?
set -e
[ $status -ne 0 ]
# -----------------------------------------------------
# Case 3: inputShortDelayedDescriptorReplicationFactor
# -----------------------------------------------------
#input=${data_dir}/bufr/bssh_178.bufr
#cat > $tempRules <<EOF
#set inputShortDelayedDescriptorReplicationFactor= {
# 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1};
#EOF
#${tools_dir}/codes_bufr_filter $tempRules $input
rm -f $tempRules $tempBufr