Skip to content

Inconsistent result when writing negative float into int32 #2098

@MonteePoke

Description

@MonteePoke

Minimal code to reproduce:

import {Field, Message} from 'protobufjs';

export class DataPacketCacheDto extends Message<DataPacketCacheDto> {
    @Field.d(1, 'float')
    f: number;

    @Field.d(2, 'int32')
    f2: number;

    @Field.d(3, 'int32')
    f3: number;
}

const message = new DataPacketCacheDto({
    f: 1097.300048828125,
    f2: 1.793662034335766e-43,
    f3: -2.0975153105823492e-14,
});

const buffer = Buffer.from(DataPacketCacheDto.encode(message).finish());

console.log(buffer.toString('hex'));

const decodedPacket: DataPacketCacheDto = (DataPacketCacheDto.toObject(DataPacketCacheDto.decode(buffer as Buffer), {
    defaults: true,
}) as DataPacketCacheDto);

console.log(decodedPacket);

Expected result:
Error: invalid wire type

Actual result
Every run outputs a different result:

  1. Trying to encode results in error:
            throw Error("invalid wire type " + wireType + " at offset " + this.pos);
                  ^
Error: invalid wire type 4 at offset 11
  1. Some runs manage to encode message into a buffer, but the buffer can't be decoded:
0d9a298944100018008ab8346c0100008891

E:\Projects\protobuf_test\node_modules\protobufjs\src\reader.js:13
    return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len)
;
           ^
RangeError: index out of range: 13 + 108 > 18
  1. Other times decoding the buffer succeeds but, field values aren't the same as before encodingOutput:
0d9a2989441000180000000034090000c8c0
{ f: -6.25, f2: 0, f3: 0 }

Observations:

  • positive float are rounded;
  • buffer is simingly random;
  • indexes in error messages are random;

package.json

{
  "dependencies": {
    "protobufjs": "7.5.4"
  },
  "devDependencies": {
    "ts-node": "9.1.1",
    "typescript": "4.2.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "paths": {}
  },
  "exclude": ["node_modules", "dist"]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions