added check on the size of the data section ECC-108

This commit is contained in:
Enrico Fucile 2015-04-30 16:21:17 +01:00
parent 1c1d7f132c
commit 5d1f64aa78
3 changed files with 98 additions and 24 deletions

View File

@ -54,6 +54,7 @@
MEMBERS = int bitmapCurrent
MEMBERS = grib_accessors_list* dataAccessors
MEMBERS = int unpackMode
MEMBERS = int bitsToEndData
END_CLASS_DEF
@ -117,6 +118,7 @@ typedef struct grib_accessor_bufr_data_array {
int bitmapCurrent;
grib_accessors_list* dataAccessors;
int unpackMode;
int bitsToEndData;
} grib_accessor_bufr_data_array;
extern grib_accessor_class* grib_accessor_class_gen;
@ -248,6 +250,7 @@ static void init(grib_accessor* a,const long v, grib_arguments* params)
a->parent->h->unpacked=0;
a->length = init_length(a);
self->bitsToEndData=a->length*8;
self->unpackMode=CODES_BUFR_UNPACK_STRUCTURE;
/* Assert(a->length>=0); */
@ -263,6 +266,14 @@ static void clean_string(char* s,int len) {
}
}
static int check_end_data(grib_context* c,grib_accessor_bufr_data_array* self,int size) {
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tbitsToEndData=%ld elementSize=%ld", self->bitsToEndData,size);
self->bitsToEndData-=size;
if (self->bitsToEndData<0)
return GRIB_DECODING_ERROR;
return 0;
}
static void self_clear(grib_context* c,grib_accessor_bufr_data_array* self) {
grib_context_free(c,self->canBeMissing);
grib_vdarray_delete_content(c,self->numericValues);
@ -352,20 +363,27 @@ static int get_descriptors(grib_accessor* a) {
}
static void decode_string_array(grib_context* c,unsigned char* data,long* pos, int i,
grib_accessor_bufr_data_array* self) {
grib_accessor_bufr_data_array* self,int *err) {
char* sval=0;
int j,modifiedWidth,modifiedReference,width;
double modifiedFactor;
modifiedWidth= self->expanded->v[i]->width;
modifiedReference= self->expanded->v[i]->reference;
modifiedFactor= self->expanded->v[i]->factor;
sval=(char*)grib_context_malloc_clear(c,modifiedWidth/8+1);
*err=check_end_data(c,self,modifiedWidth);
if (*err) return ;
grib_decode_string(data,pos,modifiedWidth/8,sval);
clean_string(sval,modifiedWidth/8);
*err=check_end_data(c,self,6);
if (*err) return ;
width=grib_decode_unsigned_long(data,pos,6);
if (width) {
grib_context_free(c,sval);
*err=check_end_data(c,self,width*8*self->numberOfSubsets);
if (*err) return ;
for (j=0;j<self->numberOfSubsets;j++) {
sval=(char*)grib_context_malloc_clear(c,width+1);
grib_decode_string(data,pos,width,sval);
@ -381,22 +399,29 @@ static void decode_string_array(grib_context* c,unsigned char* data,long* pos, i
}
static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long* pos,int i,
grib_accessor_bufr_data_array* self) {
grib_accessor_bufr_data_array* self,int *err) {
grib_darray* ret=NULL;
int j;
unsigned long lval;
int localReference,localWidth,modifiedWidth,modifiedReference;
double modifiedFactor,dval;
*err=0;
modifiedReference= self->expanded->v[i]->reference;
modifiedFactor= self->expanded->v[i]->factor;
modifiedWidth= self->expanded->v[i]->width;
*err=check_end_data(c,self,modifiedWidth+6);
if (*err) return NULL;
lval=grib_decode_unsigned_long(data,pos,modifiedWidth);
localReference=(long)lval+modifiedReference;
localWidth=grib_decode_unsigned_long(data,pos,6);
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tlocalWidth=%ld",localWidth);
ret=grib_darray_new(c,100,100);
if (localWidth) {
*err=check_end_data(c,self,localWidth*self->numberOfSubsets);
if (*err) return NULL;
for (j=0;j<self->numberOfSubsets;j++) {
lval=grib_decode_unsigned_long(data,pos,localWidth);
if (grib_is_all_bits_one(lval,localWidth) && self->canBeMissing[i]) {
@ -419,12 +444,16 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
}
static char* decode_string_value(grib_context* c,unsigned char* data,long* pos, int i,
grib_accessor_bufr_data_array* self) {
grib_accessor_bufr_data_array* self,int *err) {
char* sval=0;
int len;
*err=0;
len= self->expanded->v[i]->width / 8;
*err=check_end_data(c,self,self->expanded->v[i]->width);
if (*err) return NULL;
sval=(char*)grib_context_malloc_clear(c,len+1);
grib_decode_string(data,pos,len,sval);
@ -434,15 +463,20 @@ static char* decode_string_value(grib_context* c,unsigned char* data,long* pos,
}
static double decode_double_value(grib_context* c,unsigned char* data,long* pos,int i,
grib_accessor_bufr_data_array* self) {
grib_accessor_bufr_data_array* self,int* err) {
unsigned long lval;
int modifiedWidth,modifiedReference;
double modifiedFactor,dval;
double modifiedFactor;
double dval=0;
*err=0;
modifiedReference= self->expanded->v[i]->reference;
modifiedFactor= self->expanded->v[i]->factor;
modifiedWidth= self->expanded->v[i]->width;
*err=check_end_data(c,self,modifiedWidth);
if (*err) return dval;
lval=grib_decode_unsigned_long(data,pos,modifiedWidth);
if (grib_is_all_bits_one(lval,modifiedWidth) && self->canBeMissing[i]) {
dval=GRIB_MISSING_DOUBLE;
@ -452,17 +486,21 @@ static double decode_double_value(grib_context* c,unsigned char* data,long* pos,
return dval;
}
static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self,int subsetIndex,
static int decode_element(grib_context* c,grib_accessor_bufr_data_array* self,int subsetIndex,
unsigned char* data,long *pos,int i,grib_darray* dval,grib_sarray* sval) {
grib_darray* dar=0;
grib_sarray* sar=0;
int index=0,ii;
char* csval=0;
double cdval=0,x;
int err=0;
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tcode=%6.6ld width=%ld",
self->expanded->v[i]->code,self->expanded->v[i]->width);
if (self->expanded->v[i]->type==BUFR_DESCRIPTOR_TYPE_STRING) {
/* string */
if (self->compressedData) {
decode_string_array(c,data,pos,i,self);
decode_string_array(c,data,pos,i,self,&err);
index=grib_sarray_used_size(self->stringValues)/self->numberOfSubsets;
dar=grib_darray_new(c,self->numberOfSubsets,10);
index=self->numberOfSubsets*(index-1);
@ -472,7 +510,7 @@ static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self,i
}
grib_vdarray_push(c,self->numericValues,dar);
} else {
csval=decode_string_value(c,data,pos,i,self);
csval=decode_string_value(c,data,pos,i,self,&err);
grib_sarray_push(c,self->stringValues,csval);
index=grib_sarray_used_size(self->stringValues);
cdval=index*1000+self->expanded->v[i]->width / 8;
@ -481,13 +519,14 @@ static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self,i
} else {
/* numeric or codetable or flagtable */
if (self->compressedData) {
dar=decode_double_array(c,data,pos,i,self);
dar=decode_double_array(c,data,pos,i,self,&err);
grib_vdarray_push(c,self->numericValues,dar);
} else {
cdval=decode_double_value(c,data,pos,i,self);
cdval=decode_double_value(c,data,pos,i,self,&err);
grib_darray_push(c,dval,cdval);
}
}
return err;
}
static int build_bitmap(grib_accessor_bufr_data_array *self,unsigned char* data,long* pos,grib_iarray* elementsDescriptorsIndex,int iBitmapOperator) {
@ -499,6 +538,7 @@ static int build_bitmap(grib_accessor_bufr_data_array *self,unsigned char* data,
bufr_descriptor** descriptors=self->expanded->v;
long* edi=elementsDescriptorsIndex->v;
int iel=grib_iarray_used_size(elementsDescriptorsIndex)-1;
int err=0;
switch (descriptors[iBitmapOperator]->code) {
case 236000:
@ -513,6 +553,7 @@ static int build_bitmap(grib_accessor_bufr_data_array *self,unsigned char* data,
i=iDelayedReplication;
if (self->compressedData) {
ppos=*pos;
if (err) return err;
localReference=grib_decode_unsigned_long(data,pos,descriptors[i]->width)+descriptors[i]->reference;
width=grib_decode_unsigned_long(data,pos,6);
*pos=ppos;
@ -524,6 +565,7 @@ static int build_bitmap(grib_accessor_bufr_data_array *self,unsigned char* data,
}
} else {
ppos=*pos;
if (err) return err;
bitmapSize=grib_decode_unsigned_long(data,pos,descriptors[i]->width)+
descriptors[i]->reference*descriptors[i]->factor;
*pos=ppos;
@ -1047,7 +1089,9 @@ static int decode_elements(grib_accessor* a) {
long pos=0;
int iss,end,elementIndex,index;
long numberOfDescriptors;
long totalSize;
bufr_descriptor** descriptors=0;
long icount;
grib_darray* dval = NULL;
grib_sarray* sval = NULL;
@ -1056,6 +1100,8 @@ static int decode_elements(grib_accessor* a) {
grib_handle* h=a->parent->h;
grib_context* c=h->context;
totalSize=self->bitsToEndData;
if (!self->do_decode) return 0;
self->do_decode=0;
a->parent->h->unpacked=1;
@ -1086,11 +1132,14 @@ static int decode_elements(grib_accessor* a) {
for (iss=0;iss<end;iss++) {
elementsDescriptorsIndex=grib_iarray_new(c,100,100);
icount=1;
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: subsetNumber=%ld", iss+1);
if (!self->compressedData) {
dval=grib_darray_new(c,100,100);
/* sval=grib_sarray_new(c,10,10); */
}
for (i=0;i<numberOfDescriptors;i++) {
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: elementNumber=%ld code=%ld", icount++,descriptors[i]->code);
elementIndex=grib_iarray_used_size(elementsDescriptorsIndex);
switch(descriptors[i]->F) {
case 0:
@ -1098,7 +1147,8 @@ static int decode_elements(grib_accessor* a) {
grib_iarray_push(elementsDescriptorsIndex,i);
if (descriptors[i]->code==31031 && !is_bitmap_start_defined(self))
self->bitmapStart=grib_iarray_used_size(elementsDescriptorsIndex)-1;
decode_element(c,self,iss,data,&pos,i,dval,sval);
err=decode_element(c,self,iss,data,&pos,i,dval,sval);
if (err) return err;
break;
case 1:
/* Delayed replication */
@ -1109,16 +1159,23 @@ static int decode_elements(grib_accessor* a) {
n[inr]=numberOfElementsToRepeat[inr];
i++;
if (self->compressedData) {
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tdelayed replication localReference width=%ld", descriptors[i]->width);
err=check_end_data(c,self,descriptors[i]->width+6);
if (err) return err;
localReference=grib_decode_unsigned_long(data,&pos,descriptors[i]->width)+descriptors[i]->reference;
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tdelayed replication localWidth width=6");
width=grib_decode_unsigned_long(data,&pos,6);
if (width) {
/* delayed replication number is not constant. NOT IMPLEMENTED */
Assert(0);
} else {
numberOfRepetitions[inr]=localReference*descriptors[i]->factor;
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tdelayed replication value=%ld",numberOfRepetitions[inr]);
startRepetition[inr]=i;
}
} else {
err=check_end_data(c,self,descriptors[i]->width);
if (err) return err;
numberOfRepetitions[inr]=grib_decode_unsigned_long(data,&pos,descriptors[i]->width)+
descriptors[i]->reference*descriptors[i]->factor;
startRepetition[inr]=i;
@ -1146,7 +1203,8 @@ static int decode_elements(grib_accessor* a) {
case 5:
descriptors[i]->width=descriptors[i]->Y*8;
grib_iarray_push(elementsDescriptorsIndex,i);
decode_element(c,self,iss,data,&pos,i,dval,sval);
err=decode_element(c,self,iss,data,&pos,i,dval,sval);
if (err) return err;
break;
case 22:
case 26:
@ -1172,7 +1230,8 @@ static int decode_elements(grib_accessor* a) {
/*replaced/retained values marker operator*/
if (descriptors[i]->Y==255) {
index=get_next_bitmap_descriptor_index(self,elementsDescriptorsIndex,dval);
decode_element(c,self,iss,data,&pos,index,dval,sval);
err=decode_element(c,self,iss,data,&pos,index,dval,sval);
if (err) return err;
/* self->expanded->v[index] */
grib_iarray_push(elementsDescriptorsIndex,i);
} else {
@ -1212,7 +1271,8 @@ static int decode_elements(grib_accessor* a) {
/* associated field */
if (descriptors[i]->X==99 && descriptors[i]->Y==999) {
grib_iarray_push(elementsDescriptorsIndex,i);
decode_element(c,self,iss,data,&pos,i,dval,sval);
err=decode_element(c,self,iss,data,&pos,i,dval,sval);
if (err) return err;
} else {
return GRIB_INTERNAL_ERROR;
}
@ -1267,7 +1327,7 @@ static int decode_elements(grib_accessor* a) {
static void dump(grib_accessor* a, grib_dumper* dumper)
{
decode_elements(a);
int err=decode_elements(a);
grib_dump_section(dumper,a,a->sub_section->block);

View File

@ -93,6 +93,7 @@ int grib_tool_init(grib_runtime_options* options)
if (grib_options_on("O")) {
options->dump_mode = "wmo";
json=0;
options->dump_flags = GRIB_DUMP_FLAG_CODED
| GRIB_DUMP_FLAG_OCTECT
| GRIB_DUMP_FLAG_VALUES
@ -166,17 +167,32 @@ int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h)
/* fprintf(stdout,"\"message%d\" : ",options->handle_count); */
switch (json_option[0]) {
case 'f':
grib_set_long(h,"unpack",2);
err=grib_set_long(h,"unpack",2);
if (err) {
fprintf(stdout,"\"ERROR: unable to unpack data section\"");
options->error=err;
return err;
}
a=grib_find_accessor(h,"numericValues");
al=accessor_bufr_data_array_get_dataAccessors(a);
grib_dump_bufr_flat(al,h,stdout,options->dump_mode,options->dump_flags,0);
break;
case 's':
grib_set_long(h,"unpack",1);
err=grib_set_long(h,"unpack",1);
if (err) {
fprintf(stdout,"\"ERROR: unable to unpack data section\"");
options->error=err;
return err;
}
grib_dump_content(h,stdout,options->dump_mode,options->dump_flags,0);
break;
case 'a':
grib_set_long(h,"unpack",1);
err=grib_set_long(h,"unpack",1);
if (err) {
fprintf(stdout,"\"ERROR: unable to unpack data section\"");
options->error=err;
return err;
}
options->dump_flags=GRIB_DUMP_FLAG_ALL_ATTRIBUTES;
grib_dump_content(h,stdout,options->dump_mode,options->dump_flags,0);
break;
@ -188,10 +204,8 @@ int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h)
sprintf(tmp,"MESSAGE %d ( length=%ld )",options->handle_count,length);
if (!grib_options_on("C"))
fprintf(stdout,"#============== %-38s ==============\n",tmp);
if (!strcmp(options->dump_mode,"default")) {
GRIB_CHECK_NOLINE(grib_get_string(h,"identifier",identifier,&idlen),0);
printf("%s {\n",identifier);
}
grib_set_long(h,"unpack",1);
grib_dump_content(h,stdout,options->dump_mode,options->dump_flags,0);
}
if (!strcmp(options->dump_mode,"default"))

View File

@ -327,7 +327,7 @@ static int grib_tool_without_orderby(grib_runtime_options* options)
options->error=err;
if (!h) {
fprintf(dump_file,"\t\t\"Error: unreadable message\"\n");
fprintf(dump_file,"\t\t\"ERROR: unreadable message\"\n");
failed=(grib_failed*)grib_context_malloc_clear(c,sizeof(grib_failed));
failed->count=infile->handle_count;
@ -378,7 +378,7 @@ static int grib_tool_without_orderby(grib_runtime_options* options)
grib_tool_finalise_action(options);
return 0;
return options->error;
}
static int navigate(grib_field_tree* fields,grib_runtime_options* options)