mirror of https://github.com/ecmwf/eccodes.git
ECC-1777: Validate dataDate and dataTime on input
This commit is contained in:
parent
8b4d1eb323
commit
e2368676b3
|
@ -213,6 +213,38 @@ int is_date_valid(long year, long month, long day, long hour, long minute, doubl
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Return 1 if input date is valid. Otherwise 0
|
||||
// Note: In the 24-hour time notation, the day begins at midnight, 00:00 or 0:00,
|
||||
// and the last minute of the day begins at 23:59.
|
||||
// Where convenient, the notation 24:00 may also be used to refer to midnight
|
||||
// at the end of a given date — that is, 24:00 of one day is the same time
|
||||
// as 00:00 of the following day
|
||||
int is_time_valid(long number)
|
||||
{
|
||||
// number should be 4 digits i.e., HHMM
|
||||
// Check if the number is a four-digit integer
|
||||
if (number < 0 || number > 9999) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Extract hours and minutes
|
||||
long hours = number / 100; // Get the first two digits as hours
|
||||
long minutes = number % 100; // Get the last two digits as minutes
|
||||
|
||||
// Check if hours are within the valid range (00-23)
|
||||
if (hours < 0 || hours > 24) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if minutes are within the valid range (00-59)
|
||||
if (minutes < 0 || minutes > 59) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// All checks pass
|
||||
return 1;
|
||||
}
|
||||
|
||||
static float float_epsilon(void)
|
||||
{
|
||||
float floatEps = 1.0;
|
||||
|
|
|
@ -1328,6 +1328,7 @@ char* codes_getenv(const char* name);
|
|||
int codes_check_grib_ieee_packing_value(int value);
|
||||
int codes_flush_sync_close_file(FILE* f);
|
||||
int is_date_valid(long year, long month, long day, long hour, long minute, double second);
|
||||
int is_time_valid(long number); // number is HHMM
|
||||
int compute_scaled_value_and_scale_factor(double input, int64_t scaled_value_max, int64_t scale_factor_max, int64_t* ret_value, int64_t* ret_factor);
|
||||
|
||||
/* grib_util.cc*/
|
||||
|
|
|
@ -123,9 +123,9 @@ static void dump(grib_accessor* a, grib_dumper* dumper)
|
|||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
int ret = 0;
|
||||
grib_accessor_g2date* self = (grib_accessor_g2date*)a;
|
||||
const grib_accessor_g2date* self = (grib_accessor_g2date*)a;
|
||||
|
||||
int ret = 0;
|
||||
long year = 0;
|
||||
long month = 0;
|
||||
long day = 0;
|
||||
|
@ -145,13 +145,12 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
/* TODO: Check for a valid date */
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
int ret;
|
||||
long v = val[0];
|
||||
grib_accessor_g2date* self = (grib_accessor_g2date*)a;
|
||||
const grib_accessor_g2date* self = (grib_accessor_g2date*)a;
|
||||
|
||||
int ret = GRIB_SUCCESS;
|
||||
long v = val[0];
|
||||
long year = 0;
|
||||
long month = 0;
|
||||
long day = 0;
|
||||
|
@ -165,6 +164,12 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
v %= 100;
|
||||
day = v;
|
||||
|
||||
if (!is_date_valid(year, month, day, 0, 0, 0)) {
|
||||
// ECC-1777: For now just a warning. Will later change to an error
|
||||
fprintf(stderr, "ECCODES WARNING : %s:%s: Date is not valid! year=%ld month=%ld day=%ld\n",
|
||||
a->cclass->name, __func__, year, month, day);
|
||||
}
|
||||
|
||||
if ((ret = grib_set_long_internal(grib_handle_of_accessor(a), self->day, day)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
if ((ret = grib_set_long_internal(grib_handle_of_accessor(a), self->month, month)) != GRIB_SUCCESS)
|
||||
|
|
|
@ -126,12 +126,11 @@ static void dump(grib_accessor* a, grib_dumper* dumper)
|
|||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
int ret = 0;
|
||||
grib_accessor_time* self = (grib_accessor_time*)a;
|
||||
long hour = 0;
|
||||
long minute = 0;
|
||||
long second = 0;
|
||||
grib_handle* hand = grib_handle_of_accessor(a);
|
||||
const grib_accessor_time* self = (grib_accessor_time*)a;
|
||||
|
||||
int ret = 0;
|
||||
long hour = 0, minute = 0, second = 0;
|
||||
grib_handle* hand = grib_handle_of_accessor(a);
|
||||
|
||||
if ((ret = grib_get_long_internal(hand, self->hour, &hour)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
@ -160,54 +159,24 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
// In the 24-hour time notation, the day begins at midnight, 00:00 or 0:00,
|
||||
// and the last minute of the day begins at 23:59.
|
||||
// Where convenient, the notation 24:00 may also be used to refer to midnight
|
||||
// at the end of a given date — that is, 24:00 of one day is the same time
|
||||
// as 00:00 of the following day
|
||||
#if 0
|
||||
static bool isValidTime(long number)
|
||||
{
|
||||
// Check if the number is a four-digit integer
|
||||
if (number < 0 || number > 9999) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract hours and minutes
|
||||
long hours = number / 100; // Get the first two digits as hours
|
||||
long minutes = number % 100; // Get the last two digits as minutes
|
||||
|
||||
// Check if hours are within the valid range (00-23)
|
||||
if (hours < 0 || hours > 24) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if minutes are within the valid range (00-59)
|
||||
if (minutes < 0 || minutes > 59) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All checks pass
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
int ret = 0;
|
||||
long v = val[0];
|
||||
grib_accessor_time* self = (grib_accessor_time*)a;
|
||||
grib_handle* hand = grib_handle_of_accessor(a);
|
||||
long hour = 0;
|
||||
long minute = 0;
|
||||
long second = 0;
|
||||
const grib_accessor_time* self = (grib_accessor_time*)a;
|
||||
|
||||
int ret = 0;
|
||||
long v = val[0];
|
||||
grib_handle* hand = grib_handle_of_accessor(a);
|
||||
long hour = 0, minute = 0, second = 0;
|
||||
|
||||
if (*len != 1)
|
||||
return GRIB_WRONG_ARRAY_SIZE;
|
||||
|
||||
// if (!isValidTime(v)) {
|
||||
// return GRIB_ENCODING_ERROR;
|
||||
// }
|
||||
if (!is_time_valid(v)) {
|
||||
// ECC-1777: For now just a warning. Will later change to an error
|
||||
fprintf(stderr, "ECCODES WARNING : %s:%s: Time is not valid! hour=%ld min=%ld sec=%ld\n",
|
||||
a->cclass->name, __func__, hour, minute, second);
|
||||
// return GRIB_ENCODING_ERROR;
|
||||
}
|
||||
|
||||
hour = v / 100;
|
||||
minute = v % 100;
|
||||
|
|
|
@ -95,6 +95,18 @@ status=$?
|
|||
set -e
|
||||
[ $status -ne 0 ]
|
||||
|
||||
# Bad date
|
||||
# ---------
|
||||
input=$ECCODES_SAMPLES_PATH/GRIB2.tmpl
|
||||
${tools_dir}/grib_set -s dataDate=20180229 $input $outfile > $temp 2>&1
|
||||
cat $temp
|
||||
grep -q "Date is not valid" $temp
|
||||
|
||||
${tools_dir}/grib_set -s dataTime=4261 $input $outfile > $temp 2>&1
|
||||
cat $temp
|
||||
grep -q "Time is not valid" $temp
|
||||
|
||||
|
||||
# ECC-1359: string that can be converted to an integer
|
||||
# ---------------------------------------------------
|
||||
${tools_dir}/grib_set -s month:s=6 $ECCODES_SAMPLES_PATH/GRIB2.tmpl $outfile
|
||||
|
|
Loading…
Reference in New Issue