From b0db0f2b24f3e16211f2dc2ebec9a1313cf1179a Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 17 Jul 2014 18:02:49 +0100 Subject: [PATCH] GRIB-547: Corrupt gribs. Return error from grib_section_adjust_sizes --- src/action_class_section.c | 7 +++++-- src/grib_accessor_class.c | 13 ++++++++----- src/grib_api_prototypes.h | 2 +- src/grib_handle.c | 9 ++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/action_class_section.c b/src/action_class_section.c index 215acdbf3..a27d4da17 100644 --- a/src/action_class_section.c +++ b/src/action_class_section.c @@ -166,8 +166,10 @@ static int notify_change(grib_action* act, grib_accessor * notified, tmp_handle->use_trie=1; err=grib_create_accessor(tmp_handle->root, act, &loader); + if (err) return err; - grib_section_adjust_sizes(tmp_handle->root,1,0); + err = grib_section_adjust_sizes(tmp_handle->root,1,0); + if (err) return err; grib_section_post_init(tmp_handle->root); @@ -198,7 +200,8 @@ static int notify_change(grib_action* act, grib_accessor * notified, h->trie_invalid=1; h->kid = NULL; - grib_section_adjust_sizes(h->root,1,0); + err = grib_section_adjust_sizes(h->root,1,0); + if (err) return err; grib_section_post_init(h->root); diff --git a/src/grib_accessor_class.c b/src/grib_accessor_class.c index 30f73b318..3575a29cd 100644 --- a/src/grib_accessor_class.c +++ b/src/grib_accessor_class.c @@ -213,11 +213,11 @@ void grib_section_post_init(grib_section* s) grib_section_post_init(a->sub_section); a = a->next; } - } -void grib_section_adjust_sizes(grib_section* s,int update,int depth) +int grib_section_adjust_sizes(grib_section* s,int update,int depth) { + int err = 0; grib_accessor* a = s ? s->block->first : NULL; size_t length = update ? 0 : (s?s->padding:0); size_t offset = (s && s->owner) ? s->owner->offset:0; @@ -226,13 +226,16 @@ void grib_section_adjust_sizes(grib_section* s,int update,int depth) while(a) { register long l; /* grib_section_adjust_sizes(grib_get_sub_section(a),update,depth+1); */ - grib_section_adjust_sizes(a->sub_section,update,depth+1); + err = grib_section_adjust_sizes(a->sub_section,update,depth+1); + if (err) return err; l = a->length; if(offset != a->offset) { - grib_context_log(a->parent->h->context,GRIB_LOG_DEBUG,"Offset mismatch %s A->offset %ld offset %ld\n",a->name,(long)a->offset, (long)offset); + grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, + "Offset mismatch %s A->offset %ld offset %ld\n",a->name,(long)a->offset, (long)offset); a->offset = offset; + return GRIB_DECODING_ERROR; } length += l; offset += l; @@ -275,7 +278,7 @@ void grib_section_adjust_sizes(grib_section* s,int update,int depth) if(s->owner) s->owner->length = length; s->length = length; } - + return err; } int grib_get_block_length(grib_section* s, size_t *l) diff --git a/src/grib_api_prototypes.h b/src/grib_api_prototypes.h index d574bd283..fc9598359 100644 --- a/src/grib_api_prototypes.h +++ b/src/grib_api_prototypes.h @@ -263,7 +263,7 @@ grib_section *grib_create_root_section(const grib_context *context, grib_handle grib_accessor *grib_accessor_factory(grib_section *p, grib_action *creator, const long len, grib_arguments *params); void grib_push_accessor(grib_accessor *a, grib_block_of_accessors *l); void grib_section_post_init(grib_section *s); -void grib_section_adjust_sizes(grib_section *s, int update, int depth); +int grib_section_adjust_sizes(grib_section *s, int update, int depth); int grib_get_block_length(grib_section *s, size_t *l); grib_accessor *find_paddings(grib_section *s); void grib_update_paddings(grib_section *s); diff --git a/src/grib_handle.c b/src/grib_handle.c index 40e1a9d15..752412d4f 100644 --- a/src/grib_handle.c +++ b/src/grib_handle.c @@ -197,6 +197,7 @@ static void check_definitions_version(grib_handle* h) static grib_handle* grib_handle_create ( grib_handle *gl, grib_context* c,void* data, size_t buflen ) { grib_action* next = NULL; + int err = 0; if ( gl == NULL ) return NULL; @@ -237,7 +238,13 @@ static grib_handle* grib_handle_create ( grib_handle *gl, grib_context* c,void* next = next->next; } - grib_section_adjust_sizes ( gl->root,0,0 ); + err = grib_section_adjust_sizes ( gl->root,0,0 ); + if (err) + { + grib_handle_delete ( gl ); + return NULL; + } + grib_section_post_init ( gl->root ); check_definitions_version(gl);