Coverage Report

Created: 2025-12-03 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/grib/degrib/g2clib/g2_getfld.c
Line
Count
Source
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <assert.h>
4
#include "grib2.h"
5
6
g2int g2_getfld(unsigned char *cgrib,g2int cgrib_length, g2int ifldnum,g2int unpack,g2int expand,
7
                gribfield **gfld)
8
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
9
//                .      .    .                                       .
10
// SUBPROGRAM:    g2_getfld
11
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-28
12
//
13
// ABSTRACT: This subroutine returns all the metadata, template values,
14
//   Bit-map ( if applicable ), and the unpacked data for a given data
15
//   field.  All of the information returned is stored in a gribfield
16
//   structure, which is defined in file grib2.h.
17
//   Users of this routine will need to include "grib2.h" in their source
18
//   code that calls this routine.  Each component of the gribfield
19
//   struct is also described in the OUTPUT ARGUMENTS section below.
20
//
21
//   Since there can be multiple data fields packed into a GRIB2
22
//   message, the calling routine indicates which field is being requested
23
//   with the ifldnum argument.
24
//
25
// PROGRAM HISTORY LOG:
26
// 2002-10-28  Gilbert
27
//
28
// USAGE:    #include "grib2.h"
29
//           int g2_getfld(unsigned char *cgrib,g2int ifldnum,g2int unpack,
30
//                         g2int expand,gribfield **gfld)
31
//   INPUT ARGUMENTS:
32
//     cgrib    - Character pointer to the GRIB2 message
33
//     ifldnum  - Specifies which field in the GRIB2 message to return.
34
//     unpack   - Boolean value indicating whether to unpack bitmap/data field
35
//                1 = unpack bitmap (if present) and data values
36
//                0 = do not unpack bitmap and data values
37
//     expand   - Boolean value indicating whether the data points should be
38
//                expanded to the correspond grid, if a bit-map is present.
39
//                1 = if possible, expand data field to grid, inserting zero
40
//                    values at gridpoints that are bitmapped out.
41
//                    (SEE REMARKS2)
42
//                0 = do not expand data field, leaving it an array of
43
//                    consecutive data points for each "1" in the bitmap.
44
//                This argument is ignored if unpack == 0 OR if the
45
//                returned field does not contain a bit-map.
46
//
47
//   OUTPUT ARGUMENT:
48
//     gribfield gfld; - pointer to structure gribfield containing
49
//                       all decoded data for the data field.
50
//
51
//        gfld->version = GRIB edition number ( currently 2 )
52
//        gfld->discipline = Message Discipline ( see Code Table 0.0 )
53
//        gfld->idsect = Contains the entries in the Identification
54
//                        Section ( Section 1 )
55
//                        This element is a pointer to an array
56
//                        that holds the data.
57
//            gfld->idsect[0]  = Identification of originating Centre
58
//                                    ( see Common Code Table C-1 )
59
//                             7 - US National Weather Service
60
//            gfld->idsect[1]  = Identification of originating Sub-centre
61
//            gfld->idsect[2]  = GRIB Master Tables Version Number
62
//                                    ( see Code Table 1.0 )
63
//                             0 - Experimental
64
//                             1 - Initial operational version number
65
//            gfld->idsect[3]  = GRIB Local Tables Version Number
66
//                                    ( see Code Table 1.1 )
67
//                             0     - Local tables not used
68
//                             1-254 - Number of local tables version used
69
//            gfld->idsect[4]  = Significance of Reference Time (Code Table 1.2)
70
//                             0 - Analysis
71
//                             1 - Start of forecast
72
//                             2 - Verifying time of forecast
73
//                             3 - Observation time
74
//            gfld->idsect[5]  = Year ( 4 digits )
75
//            gfld->idsect[6]  = Month
76
//            gfld->idsect[7)  = Day
77
//            gfld->idsect[8]  = Hour
78
//            gfld->idsect[9]  = Minute
79
//            gfld->idsect[10]  = Second
80
//            gfld->idsect[11]  = Production status of processed data
81
//                                    ( see Code Table 1.3 )
82
//                              0 - Operational products
83
//                              1 - Operational test products
84
//                              2 - Research products
85
//                              3 - Re-analysis products
86
//            gfld->idsect[12]  = Type of processed data ( see Code Table 1.4 )
87
//                              0  - Analysis products
88
//                              1  - Forecast products
89
//                              2  - Analysis and forecast products
90
//                              3  - Control forecast products
91
//                              4  - Perturbed forecast products
92
//                              5  - Control and perturbed forecast products
93
//                              6  - Processed satellite observations
94
//                              7  - Processed radar observations
95
//        gfld->idsectlen = Number of elements in gfld->idsect[].
96
//        gfld->local   = Pointer to character array containing contents
97
//                       of Local Section 2, if included
98
//        gfld->locallen = length of array gfld->local[]
99
//        gfld->ifldnum = field number within GRIB message
100
//        gfld->griddef = Source of grid definition (see Code Table 3.0)
101
//                      0 - Specified in Code table 3.1
102
//                      1 - Predetermined grid Defined by originating centre
103
//        gfld->ngrdpts = Number of grid points in the defined grid.
104
//        gfld->numoct_opt = Number of octets needed for each
105
//                          additional grid points definition.
106
//                          Used to define number of
107
//                          points in each row ( or column ) for
108
//                          non-regular grids.
109
//                          = 0, if using regular grid.
110
//        gfld->interp_opt = Interpretation of list for optional points
111
//                          definition.  (Code Table 3.11)
112
//        gfld->igdtnum = Grid Definition Template Number (Code Table 3.1)
113
//        gfld->igdtmpl  = Contains the data values for the specified Grid
114
//                         Definition Template ( NN=gfld->igdtnum ).  Each
115
//                         element of this integer array contains an entry (in
116
//                         the order specified) of Grid Definition Template 3.NN
117
//                         This element is a pointer to an array
118
//                         that holds the data.
119
//        gfld->igdtlen = Number of elements in gfld->igdtmpl[].  i.e. number of
120
//                       entries in Grid Definition Template 3.NN
121
//                       ( NN=gfld->igdtnum ).
122
//        gfld->list_opt  = (Used if gfld->numoct_opt .ne. 0)  This array
123
//                          contains the number of grid points contained in
124
//                          each row ( or column ).  (part of Section 3)
125
//                          This element is a pointer to an array
126
//                          that holds the data.  This pointer is nullified
127
//                          if gfld->numoct_opt=0.
128
//        gfld->num_opt = (Used if gfld->numoct_opt .ne. 0)
129
//                        The number of entries
130
//                       in array ideflist.  i.e. number of rows ( or columns )
131
//                       for which optional grid points are defined.  This value
132
//                       is set to zero, if gfld->numoct_opt=0.
133
//        gfdl->ipdtnum = Product Definition Template Number(see Code Table 4.0)
134
//        gfld->ipdtmpl  = Contains the data values for the specified Product
135
//                         Definition Template ( N=gfdl->ipdtnum ). Each element
136
//                         of this integer array contains an entry (in the
137
//                         order specified) of Product Definition Template 4.N.
138
//                         This element is a pointer to an array
139
//                         that holds the data.
140
//        gfld->ipdtlen = Number of elements in gfld->ipdtmpl[].  i.e. number of
141
//                       entries in Product Definition Template 4.N
142
//                       ( N=gfdl->ipdtnum ).
143
//        gfld->coord_list  = Real array containing floating point values
144
//                            intended to document the vertical discretisation
145
//                            associated to model data on hybrid coordinate
146
//                            vertical levels.  (part of Section 4)
147
//                            This element is a pointer to an array
148
//                            that holds the data.
149
//        gfld->num_coord = number of values in array gfld->coord_list[].
150
//        gfld->ndpts = Number of data points unpacked and returned.
151
//        gfld->idrtnum = Data Representation Template Number
152
//                       ( see Code Table 5.0)
153
//        gfld->idrtmpl  = Contains the data values for the specified Data
154
//                         Representation Template ( N=gfld->idrtnum ).  Each
155
//                         element of this integer array contains an entry
156
//                         (in the order specified) of Product Definition
157
//                         Template 5.N.
158
//                         This element is a pointer to an array
159
//                         that holds the data.
160
//        gfld->idrtlen = Number of elements in gfld->idrtmpl[].  i.e. number
161
//                       of entries in Data Representation Template 5.N
162
//                       ( N=gfld->idrtnum ).
163
//        gfld->unpacked = logical value indicating whether the bitmap and
164
//                        data values were unpacked.  If false,
165
//                        gfld->bmap and gfld->fld pointers are nullified.
166
//        gfld->expanded = Logical value indicating whether the data field
167
//                         was expanded to the grid in the case where a
168
//                         bit-map is present.  If true, the data points in
169
//                         gfld->fld match the grid points and zeros were
170
//                         inserted at grid points where data was bit-mapped
171
//                         out.  If false, the data values in gfld->fld were
172
//                         not expanded to the grid and are just a consecutive
173
//                         array of data points corresponding to each value of
174
//                         "1" in gfld->bmap.
175
//        gfld->ibmap = Bitmap indicator ( see Code Table 6.0 )
176
//                     0 = bitmap applies and is included in Section 6.
177
//                     1-253 = Predefined bitmap applies
178
//                     254 = Previously defined bitmap applies to this field
179
//                     255 = Bit map does not apply to this product.
180
//        gfld->bmap  = integer array containing decoded bitmap,
181
//                      if gfld->ibmap=0 or gfld->ibap=254.  Otherwise nullified
182
//                      This element is a pointer to an array
183
//                      that holds the data.
184
//        gfld->fld  = Array of gfld->ndpts unpacked data points.
185
//                     This element is a pointer to an array
186
//                     that holds the data.
187
//
188
//
189
//   RETURN VALUES:
190
//     ierr     - Error return code.
191
//                0 = no error
192
//                1 = Beginning characters "GRIB" not found.
193
//                2 = GRIB message is not Edition 2.
194
//                3 = The data field request number was not positive.
195
//                4 = End string "7777" found, but not where expected.
196
//                6 = GRIB message did not contain the requested number of
197
//                    data fields.
198
//                7 = End string "7777" not found at end of message.
199
//                8 = Unrecognized Section encountered.
200
//                9 = Data Representation Template 5.NN not yet implemented.
201
//               15 = Error unpacking Section 1.
202
//               16 = Error unpacking Section 2.
203
//               10 = Error unpacking Section 3.
204
//               11 = Error unpacking Section 4.
205
//               12 = Error unpacking Section 5.
206
//               13 = Error unpacking Section 6.
207
//               14 = Error unpacking Section 7.
208
//               17 = Previous bitmap specified, yet none exists.
209
//
210
// REMARKS: Note that struct gribfield is allocated by this routine and it
211
//          also contains pointers to many arrays of data that were allocated
212
//          during decoding.  Users are encouraged to free up this memory,
213
//          when it is no longer needed, by an explicit call to routine g2_free.
214
//          EXAMPLE:
215
//              #include "grib2.h"
216
//              gribfield *gfld;
217
//              ret=g2_getfld(cgrib,1,1,1,&gfld);
218
//                ...
219
//              g2_free(gfld);
220
//
221
//          Routine g2_info can be used to first determine
222
//          how many data fields exist in a given GRIB message.
223
//
224
// REMARKS2: It may not always be possible to expand a bit-mapped data field.
225
//           If a pre-defined bit-map is used and not included in the GRIB2
226
//           message itself, this routine would not have the necessary
227
//           information to expand the data.  In this case, gfld->expanded would
228
//           would be set to 0 (false), regardless of the value of input
229
//           argument expand.
230
//
231
// ATTRIBUTES:
232
//   LANGUAGE: C
233
//   MACHINE:
234
//
235
//$$$
236
15.8k
{
237
238
15.8k
      g2int have3,have4,have5,have6,have7,ierr,jerr;
239
15.8k
      g2int numfld,j,n,istart,iofst,ipos;
240
15.8k
      g2int disc,ver,lensec0,lengrib,lensec,isecnum;
241
15.8k
      g2int  *igds;
242
15.8k
      g2int *bmpsave;
243
15.8k
      g2float *newfld;
244
15.8k
      gribfield  *lgfld;
245
15.8k
      int iofst_last_sect6 = -1;
246
247
15.8k
      have3=0;
248
15.8k
      have4=0;
249
15.8k
      have5=0;
250
15.8k
      have6=0;
251
15.8k
      have7=0;
252
15.8k
      ierr=0;
253
15.8k
      numfld=0;
254
255
15.8k
      lgfld=(gribfield *)malloc(sizeof(gribfield));
256
15.8k
      *gfld=lgfld;
257
258
15.8k
      lgfld->locallen=0;
259
15.8k
      lgfld->idsect=0;
260
15.8k
      lgfld->local=0;
261
15.8k
      lgfld->list_opt=0;
262
15.8k
      lgfld->igdtmpl=0;
263
15.8k
      lgfld->ipdtmpl=0;
264
15.8k
      lgfld->idrtmpl=0;
265
15.8k
      lgfld->coord_list=0;
266
15.8k
      lgfld->bmap=0;
267
15.8k
      lgfld->fld=0;
268
15.8k
      lgfld->ngrdpts=0;
269
//
270
//  Check for valid request number
271
//
272
15.8k
      if (ifldnum <= 0) {
273
0
        printf("g2_getfld: Request for field number must be positive.\n");
274
0
        ierr=3;
275
0
        return(ierr);
276
0
      }
277
//
278
//  Check for beginning of GRIB message in the first 100 bytes
279
//
280
15.8k
      istart=-1;
281
15.8k
      for (j=0;j<100;j++) {
282
15.8k
        if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' &&
283
15.8k
            cgrib[j+3]=='B') {
284
15.8k
          istart=j;
285
15.8k
          break;
286
15.8k
        }
287
15.8k
      }
288
15.8k
      if (istart == -1) {
289
0
        printf("g2_getfld:  Beginning characters GRIB not found.\n");
290
0
        ierr=1;
291
0
        return(ierr);
292
0
      }
293
//
294
//  Unpack Section 0 - Indicator Section
295
//
296
15.8k
      iofst=8*(istart+6);
297
15.8k
      gbit(cgrib,&disc,iofst,8);     // Discipline
298
15.8k
      iofst=iofst+8;
299
15.8k
      gbit(cgrib,&ver,iofst,8);     // GRIB edition number
300
15.8k
      iofst=iofst+8;
301
15.8k
      iofst=iofst+32;
302
15.8k
      gbit(cgrib,&lengrib,iofst,32);        // Length of GRIB message
303
15.8k
      iofst=iofst+32;
304
15.8k
      lensec0=16;
305
15.8k
      ipos=istart+lensec0;
306
//
307
//  Currently handles only GRIB Edition 2.
308
//
309
15.8k
      if (ver != 2) {
310
0
        printf("g2_getfld: can only decode GRIB edition 2.\n");
311
0
        ierr=2;
312
0
        return(ierr);
313
0
      }
314
//
315
//  Loop through the remaining sections keeping track of the
316
//  length of each.  Also keep the latest Grid Definition Section info.
317
//  Unpack the requested field number.
318
//
319
92.4k
      for (;;) {
320
        //    Check to see if we are at end of GRIB message
321
92.4k
        if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' &&
322
0
            cgrib[ipos+3]=='7') {
323
0
          ipos=ipos+4;
324
          //    If end of GRIB message not where expected, issue error
325
0
          if (ipos != (istart+lengrib)) {
326
0
            printf("g2_getfld: '7777' found, but not where expected.\n");
327
0
            ierr=4;
328
0
            return(ierr);
329
0
          }
330
0
          break;
331
0
        }
332
        //     Get length of Section and Section number
333
        //iofst=(ipos-1)*8;
334
92.4k
        iofst=ipos*8;
335
92.4k
        gbit(cgrib,&lensec,iofst,32);        // Get Length of Section
336
92.4k
        iofst=iofst+32;
337
92.4k
        gbit(cgrib,&isecnum,iofst,8);         // Get Section number
338
92.4k
        iofst=iofst+8;
339
        //printf(" lensec= %ld    secnum= %ld \n",lensec,isecnum);
340
        //
341
        //  Check to see if section number is valid
342
        //
343
92.4k
        if ( isecnum<1 || isecnum>7 ) {
344
0
          printf("g2_getfld: Unrecognized Section Encountered=%d\n",isecnum);
345
0
          ierr=8;
346
0
          return(ierr);
347
0
        }
348
        //
349
        //   If found Section 1, decode elements in Identification Section
350
        //
351
92.4k
        if (isecnum == 1) {
352
15.8k
          iofst=iofst-40;       // reset offset to beginning of section
353
15.8k
          jerr=g2_unpack1(cgrib,&iofst,&lgfld->idsect,&lgfld->idsectlen);
354
15.8k
          if (jerr !=0 ) {
355
0
            ierr=15;
356
0
            return(ierr);
357
0
          }
358
15.8k
        }
359
        //
360
        //   If found Section 2, Grab local section
361
        //   Save in case this is the latest one before the requested field.
362
        //
363
92.4k
        if (isecnum == 2) {
364
6.94k
          iofst=iofst-40;       // reset offset to beginning of section
365
6.94k
          if (lgfld->local!=0) free(lgfld->local);
366
6.94k
          jerr=g2_unpack2(cgrib,&iofst,&lgfld->locallen,&lgfld->local);
367
6.94k
          if (jerr != 0) {
368
0
            ierr=16;
369
0
            return(ierr);
370
0
          }
371
6.94k
        }
372
        //
373
        //   If found Section 3, unpack the GDS info using the
374
        //   appropriate template.  Save in case this is the latest
375
        //   grid before the requested field.
376
        //
377
92.4k
        if (isecnum == 3) {
378
15.8k
          iofst=iofst-40;       // reset offset to beginning of section
379
15.8k
          if (lgfld->igdtmpl!=0) free(lgfld->igdtmpl);
380
15.8k
          if (lgfld->list_opt!=0) free(lgfld->list_opt);
381
15.8k
          jerr=g2_unpack3(cgrib,cgrib_length,&iofst,&igds,&lgfld->igdtmpl,
382
15.8k
                          &lgfld->igdtlen,&lgfld->list_opt,&lgfld->num_opt);
383
15.8k
          if (jerr == 0) {
384
15.8k
            have3=1;
385
15.8k
            lgfld->griddef=igds[0];
386
15.8k
            lgfld->ngrdpts=igds[1];
387
15.8k
            lgfld->numoct_opt=igds[2];
388
15.8k
            lgfld->interp_opt=igds[3];
389
15.8k
            lgfld->igdtnum=igds[4];
390
15.8k
            free(igds);
391
15.8k
          }
392
24
          else {
393
24
            ierr=10;
394
24
            free( igds );
395
24
            return(ierr);
396
24
          }
397
15.8k
        }
398
        //
399
        //   If found Section 4, check to see if this field is the
400
        //   one requested.
401
        //
402
92.4k
        if (isecnum == 4) {
403
15.8k
          numfld=numfld+1;
404
15.8k
          if (numfld == ifldnum) {
405
15.8k
            lgfld->discipline=disc;
406
15.8k
            lgfld->version=ver;
407
15.8k
            lgfld->ifldnum=ifldnum;
408
15.8k
            lgfld->unpacked=unpack;
409
15.8k
            lgfld->expanded=0;
410
15.8k
            iofst=iofst-40;       // reset offset to beginning of section
411
15.8k
            jerr=g2_unpack4(cgrib,cgrib_length,&iofst,&lgfld->ipdtnum,
412
15.8k
                            &lgfld->ipdtmpl,&lgfld->ipdtlen,&lgfld->coord_list,
413
15.8k
                            &lgfld->num_coord);
414
15.8k
            if (jerr == 0 || jerr == 5 )
415
15.8k
              have4=1;
416
0
            else {
417
0
              ierr=11;
418
0
              return(ierr);
419
0
            }
420
15.8k
          }
421
15.8k
        }
422
        //
423
        //   If found Section 5, check to see if this field is the
424
        //   one requested.
425
        //
426
92.4k
        if (isecnum == 5 && numfld == ifldnum) {
427
15.8k
          iofst=iofst-40;       // reset offset to beginning of section
428
15.8k
          jerr=g2_unpack5(cgrib,cgrib_length,&iofst,&lgfld->ndpts,&lgfld->idrtnum,
429
15.8k
                          &lgfld->idrtmpl,&lgfld->idrtlen);
430
15.8k
          if (jerr == 0)
431
15.8k
            have5=1;
432
0
          else {
433
0
            ierr=12;
434
0
            return(ierr);
435
0
          }
436
15.8k
        }
437
        //
438
        //   If found Section 6, Unpack bitmap.
439
        //   Save in case this is the latest
440
        //   bitmap before the requested field.
441
        //
442
92.4k
        if (isecnum == 6) {
443
15.8k
          if (numfld==ifldnum && unpack) {   // unpack bitmap
444
6.44k
            iofst=iofst-40;           // reset offset to beginning of section
445
6.44k
            bmpsave=lgfld->bmap;      // save pointer to previous bitmap
446
6.44k
            jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
447
6.44k
                         &lgfld->bmap);
448
6.44k
            if (jerr == 0) {
449
6.44k
              have6=1;
450
6.44k
              if (lgfld->ibmap == 254)     // use previously specified bitmap
451
28
                 if( bmpsave!=0 )
452
0
                    lgfld->bmap=bmpsave;
453
28
                 else {
454
455
28
                    if( ifldnum > 1 && iofst_last_sect6 > 0 )
456
0
                    {
457
                        /* Unpack the last valid section 6 we read before */
458
0
                        int iofst_backup = iofst;
459
0
                        iofst = iofst_last_sect6 - 40;
460
0
                        jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
461
0
                                        &lgfld->bmap);
462
0
                        lgfld->ibmap = 254;
463
0
                        iofst = iofst_backup;
464
0
                        if( jerr != 0 ) {
465
0
                            ierr=13;
466
0
                            return(ierr);
467
0
                        }
468
0
                    }
469
28
                    else
470
28
                    {
471
28
                        printf("g2_getfld: Prev bit-map specified, but none exist.\n");
472
28
                        ierr=17;
473
28
                        return(ierr);
474
28
                    }
475
28
                 }
476
6.42k
              else                         // get rid of it
477
6.42k
                 if( bmpsave!=0 ) free(bmpsave);
478
6.44k
            }
479
0
            else {
480
0
              ierr=13;
481
0
              return(ierr);
482
0
            }
483
6.44k
          }
484
9.35k
          else {    // do not unpack bitmap
485
9.35k
            gbit(cgrib,&lgfld->ibmap,iofst,8);      // Get BitMap Indicator
486
9.35k
            have6=1;
487
9.35k
            if( lgfld->ibmap == 0 ) {
488
                /* Save the offset of this section in case we might need to unpack it later for a later subfield */
489
0
                iofst_last_sect6 = iofst;
490
0
            }
491
9.35k
          }
492
15.8k
        }
493
        //
494
        //   If found Section 7, check to see if this field is the
495
        //   one requested.
496
        //
497
92.4k
        if (isecnum==7 && numfld==ifldnum && unpack) {
498
6.42k
          iofst=iofst-40;       // reset offset to beginning of section
499
          
500
          /* If expand is requested and we cannot do it, then early exit */
501
          /* to avoid useless operations */
502
          /* Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2183 */
503
          /* See grib2api.c : */
504
          /* Check if NCEP had problems expanding the data.  If so we currently
505
            * abort.  May need to revisit this behavior. */
506
6.42k
          if( expand )
507
6.42k
          {
508
6.42k
              if ( lgfld->ibmap != 255 && lgfld->bmap != 0 )
509
0
              {
510
0
                  if( lgfld->ngrdpts < lgfld->ndpts )
511
0
                  {
512
                      /* There are more points in the data section than in */
513
                      /* the bitmap, that doesn't make sense (bitmap only */
514
                      /* makes sense if it saves the encoding of points in */
515
                      /* the data section) */
516
0
                      ierr=14;
517
0
                      return(ierr);
518
0
                  }
519
0
              }
520
6.42k
              else if( lgfld->ngrdpts != lgfld->ndpts )
521
368
              {
522
368
                  ierr=14;
523
368
                  return(ierr);
524
368
              }
525
6.42k
          }
526
527
6.05k
          jerr=g2_unpack7(cgrib,cgrib_length,&iofst,lgfld->igdtnum,lgfld->igdtmpl,
528
6.05k
                          lgfld->idrtnum,lgfld->idrtmpl,lgfld->ndpts,
529
6.05k
                          &lgfld->fld);
530
6.05k
          if (jerr == 0) {
531
5.67k
            have7=1;
532
            //  If bitmap is used with this field, expand data field
533
            //  to grid, if possible.
534
5.67k
            if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) {
535
0
               if ( expand == 1 ) {
536
0
                  n=0;
537
0
                  newfld=(g2float *)calloc(lgfld->ngrdpts,sizeof(g2float));
538
0
                  for (j=0;j<lgfld->ngrdpts;j++) {
539
0
                      if (lgfld->bmap[j]==1)
540
0
                      {
541
0
                          if( n >= lgfld->ndpts )
542
0
                          {
543
0
                              printf("g2_getfld: overflow of lgfld->fld array\n");
544
0
                              ierr=14;
545
0
                              free(newfld);
546
0
                              return(ierr);
547
0
                          }
548
0
                          newfld[j]=lgfld->fld[n++];
549
0
                      }
550
0
                  }
551
0
                  free(lgfld->fld);
552
0
                  lgfld->fld=newfld;
553
0
                  lgfld->expanded=1;
554
0
               }
555
0
               else {
556
0
                  lgfld->expanded=0;
557
0
               }
558
0
            }
559
5.67k
            else {
560
5.67k
               if( lgfld->ngrdpts != lgfld->ndpts )
561
0
               {
562
                   /* Added by E. Rouault to fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2070 */
563
0
                   lgfld->expanded=0;
564
0
               }
565
5.67k
               else 
566
5.67k
               {
567
5.67k
                    lgfld->expanded=1;
568
5.67k
               }
569
5.67k
            }
570
5.67k
          }
571
380
          else {
572
380
            printf("g2_getfld: return from g2_unpack7 = %d \n",(int)jerr);
573
380
            ierr=14;
574
380
            return(ierr);
575
380
          }
576
6.05k
        }
577
        //
578
        //   Check to see if we read pass the end of the GRIB
579
        //   message and missed the terminator string '7777'.
580
        //
581
91.6k
        ipos=ipos+lensec;                // Update beginning of section pointer
582
91.6k
        if (ipos > (istart+lengrib)) {
583
0
          printf("g2_getfld: '7777'  not found at end of GRIB message.\n");
584
0
          ierr=7;
585
0
          return(ierr);
586
0
        }
587
        //
588
        //  If unpacking requested, return when all sections have been
589
        //  processed
590
        //
591
91.6k
        if (unpack && have3 && have4 && have5 && have6 && have7)
592
5.67k
            return(ierr);
593
        //
594
        //  If unpacking is not requested, return when sections
595
        //  3 through 6 have been processed
596
        //
597
85.9k
        if ((! unpack) && have3 && have4 && have5 && have6)
598
9.35k
            return(ierr);
599
600
85.9k
      }
601
602
//
603
//  If exited from above loop, the end of the GRIB message was reached
604
//  before the requested field was found.
605
//
606
0
      printf("g2_getfld: GRIB message contained %d different fields.\n",numfld);
607
0
      printf("g2_getfld: The request was for field %d.\n",ifldnum);
608
0
      ierr=6;
609
610
0
      return(ierr);
611
612
15.8k
}