inconsistency handling associated fields

Bug #893198 reported by cpb
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libECBUFR
Fix Committed
Medium
cpb

Bug Description

Not sure if it's compiler dependent or architecture... we've been having long-term problems with the test case BUFR/AMDAR+2xUS-v15.bufr and it's use of associated fields. For some platforms, we get different output. For example, on my 32-bit oneiric system, the decoder debug output contains:

Code: 001111 AFD: (0 bits) 01000001 01000001 01000001 STR: [AAA] (24 bits)
Code: 001112 AFD: (0 bits) 01000010 01000010 01000010 STR: [BBB] (24 bits)
Code: 204002 Code: 031021 AFD: (0 bits) 001000 IVAL=8 (0 bits)
Code: 004001 AFD: (2 bits) 00 AFD: 0x0 (0 bits) 011111011001 IVAL=2009 (12 bi
ts)
Code: 004002 AFD: (2 bits) 00 AFD: 0x0 (0 bits) 0011 IVAL=3 (4 bits)
Code: 004003 AFD: (2 bits) 00 AFD: 0x0 (0 bits) 010101 IVAL=21 (6 bits)
Code: 004004 AFD: (2 bits) 00 AFD: 0x0 (0 bits) 01010 IVAL=10 (5 bits)

While the 64-bit oneiric system gives:

Code: 001111 AFD: (0 bits) 01000001 01000001 01000001 STR: [AAA] (24 bits)
Code: 001112 AFD: (0 bits) 01000010 01000010 01000010 STR: [BBB] (24 bits)
Code: 204002 Code: 031021 AFD: (0 bits) 001000 IVAL=8 (6 bits)
Code: 004001 AFD: (2 bits) 00 AFD: 0x0 (2 bits) 011111011001 IVAL=2009 (12 bi
ts)
Code: 004002 AFD: (2 bits) 00 AFD: 0x0 (2 bits) 0011 IVAL=3 (4 bits)
Code: 004003 AFD: (2 bits) 00 AFD: 0x0 (2 bits) 010101 IVAL=21 (6 bits)
Code: 004004 AFD: (2 bits) 00 AFD: 0x0 (2 bits) 01010 IVAL=10 (5 bits)

It starts right off with differences in interpretation of the 204002 and eventually leads to different output values.

cpb (chris-beauregard)
Changed in libecbufr:
assignee: nobody → cpb (chris-beauregard)
importance: Undecided → Medium
Revision history for this message
cpb (chris-beauregard) wrote :

Part of the problem is a 32/64 bit issue. For example, take a line from bufr_dataset.c like:

  sprintf( errmsg, _("IVAL=%ld "), val );

val is of type int64_t.

The problem is that depending on the architecture, either %ld or %lld is appropriate. And when you get into constructs like:

         sprintf( errmsg, _n("AFD: 0x%lx (%d bit) ", "AFD: 0x%lx (%d bits) ", bd->value->af->nbits),
               bd->value->af->bits, bd->value->af->nbits );

where we have a mixture of uint64_t and uint16_t, things get messy.

Fixing this correctly requires using the inttypes.h header with predefined format macros. For example, to output a int64_t, you'd want to do
        sprintf(buf, "%d" PRId64 "\n", val);

Unfortunately, this does NOT integrate nicely with gettext() markup like _("IVAL=%ld "), which means things will need to be done using temp buffers. Mind you, much of that kind of translation markup might be inappropriate for the fields being output.

Revision history for this message
cpb (chris-beauregard) wrote :

For some types, we can "fix" the problem by casting fields to types which are guaranteed to be at least as large. For example:

  uint16_t val16;
  int64_t val64;
  sprintf(buf,"%u", (unsigned) val16);
  sprintf(buf,"%lld", (long long) val64);

Revision history for this message
cpb (chris-beauregard) wrote :

I suppose it'd help to point out that -Wformat indicates where we've got a problem:

bufr_dataset.c: In function 'bufr_put_numeric_compressed':
bufr_dataset.c:1056:16: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' [-Wformat]
bufr_dataset.c:1056:16: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' [-Wformat]
bufr_dataset.c:1075:16: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' [-Wformat]
bufr_dataset.c:1075:16: warning: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' [-Wformat]
bufr_dataset.c:1095:13: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'uint64_t' [-Wformat]
bufr_dataset.c:1095:13: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'uint64_t' [-Wformat]
bufr_dataset.c: In function 'bufr_put_ieeefp_compressed':
...

Revision history for this message
cpb (chris-beauregard) wrote :

Fixed. Regression tests pass on all my build platforms: 32 bit etch, lenny, squeeze, lucid, maverick, natty, oneiric, and 64bit oneiric.

Changed in libecbufr:
status: New → Fix Committed
Changed in libecbufr:
milestone: none → 0.8.4
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.