AlexanderSkvortsov / protobuf-embedded-c

Automatically exported from code.google.com/p/protobuf-embedded-c
0 stars 0 forks source link

read_raw_varint32 does not work correctly #46

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Note: The XXX_read() below used a received GB serialized from a host system 
(C#).  The serialized message encoded (from 0x520ce0cd) correctly to 
0x20cdc1b39005
1. Use a message named XXX with a uint32 field. Set value to 0x520ce0cd.
2. Call XXX_read() with a serialize GB.

What is the expected output? What do you see instead?
0x520ce0cd should be in the deserialize GB.  0xffff0ecd was the value.

What version of the product are you using? On what operating system?
1.0M4, Windows XP, target system MSp430 IAR 5.51 IDE.

Please provide any additional information below.
It appears that read_raw_varint32() is not type casting all uses of "result" 
when or'ing into "tag" (shift of 7 and 14).  I edit the routine to add the type 
casting and it now works correctly.

int read_raw_varint32(unsigned long *tag, void *_buffer, int offset) {
    signed char result;

    offset = read_raw_byte((char *)&result, _buffer, offset);
    if (result >= 0) {
        *tag = result;
        return offset;
    }
    *tag = result & 0x7f;
    offset = read_raw_byte((char *)&result, _buffer, offset);
    if (result >= 0) {
        *tag |= ((unsigned long)result) << 7;
    } else {
        *tag |= (((unsigned long)result) & 0x7f) << 7;
        offset = read_raw_byte((char *)&result, _buffer, offset);
        if (result >= 0) {
            *tag |= ((unsigned long)result) << 14;
        } else {
            *tag |= (((unsigned long)result) & 0x7f) << 14;
            offset = read_raw_byte((char *)&result, _buffer, offset);
            if (result >= 0) {
                *tag |= ((unsigned long)result) << 21;
            } else {
                *tag |= (((unsigned long)result) & 0x7f) << 21;
                offset = read_raw_byte((char *)&result, _buffer, offset);
                *tag |= ((unsigned long)result) << 28;
                if (result < 0) {
                    /* Discard upper 32 bits. */
                    int i;
                    for (i = 0; i < 5; ++ i) {
                        offset = read_raw_byte((char *)&result, _buffer, offset);
                        if (result >= 0) {
                            return offset;
                        }
                    }
                    /* Invalid state. */
                }
            }
        }
    }
    return offset;
}

Original issue reported on code.google.com by alan.joh...@gd-ais.com on 15 Aug 2013 at 3:50