Wireshark-dev: Re: [Wireshark-dev] Netflow dissector bug-to-be

From: Jakub Zawadzki <darkjames@xxxxxxxxxxxxxxxx>
Date: Sun, 7 Nov 2010 22:13:11 +0100
On Sun, Nov 07, 2010 at 03:37:36PM -0500, Hadriel Kaplan wrote:
> 
> On Nov 7, 2010, at 12:33 PM, Jakub Zawadzki wrote:
> > Have you tried adding 'U' to your #define? i.e.
> > 
> > instead of just:
> >   #define VENDOR_FOO 0xdead
> > 
> > do:
> >   #define VENDOR_FOO 0xdeadU
> > 
> > or even better:
> >    #define VENDOR_FOO G_GUINT64_CONSTANT(0xdead) /* which should result in 0xdeadLLU */
> 
> It won't help - if you force it to be bigger than an int, 

I really don't want to force it bigger than int, I just want to make it unsigned.

cause:
	(gdb) call /x (unsigned long long) (0xdead << 16)
	$1 = 0xffffffffdead0000
	(gdb) call /x (unsigned long long) (0xdeadU << 16)
	$2 = 0xdead0000

and I'm afraid in your case (VENDOR_FOO << 16) is sign extended to uint64_t.
(btw. you can check it using disassembly)

> gcc errors that the switch's case statement is not an integer... and apparently ISO C agrees with it: switch/case is defined to use an int size

Well mine[1] version of C99 standard speaks only about *integer constants*, and unsigned long long constant is still integer one.
Can't find information about int size.

gcc-4.4.4 compiles & run attached test without problem (both on -m32 -m64)
Can you try it?

[1] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf

Regards.
#include <stdio.h>
#include <stdint.h>

#define VENDOR_FOO 0xdeadU
#define BIG64_VALUE 0xdeadbeafc0debeafLLU

void test(uint64_t pen_type) {
	switch (pen_type) {
		case BIG64_VALUE:
			printf("BIG64_VALUE: %.16llx\n", pen_type);
			break;

		case (VENDOR_FOO << 16 | 3):
			printf("VENDOR_FOO: %.16llx\n", pen_type);
			break;
		
		default:
			printf("UNK: %.16llx\n", pen_type);
			break;
	}
}

int main() {
	test((VENDOR_FOO << 16) | 3);
	test(BIG64_VALUE);
	test(-1);
}