Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision lost when decode long field in browser #758

Closed
k8w opened this issue Apr 12, 2017 · 7 comments
Closed

Precision lost when decode long field in browser #758

k8w opened this issue Apr 12, 2017 · 7 comments
Labels

Comments

@k8w
Copy link

k8w commented Apr 12, 2017

protobuf.js version:
6.7.3

Reproduction code

test.proto

syntax = "proto3";

package TestProto;

message Test {
    fixed64 value = 1;
}

generate scripts:

pbjs -t static-module -w commonjs -o Test.js test.proto
npm i protobufjs

index.js

const TestProto = require('./Test').TestProto;
const Long = require('long');
var buf = TestProto.Test.encode({value: Long.fromString("6221929103415579899")}).finish();
var dec = TestProto.Test.decode(buf);
console.log(buf);
console.log(dec.value.toString());

webpack.config.js

module.exports = {
    entry: {
        app: './index.js'
    },
    output: {
        filename: 'bundle.js',
    }
}

Result

Run in node: (works well)

<Buffer 09 fb 14 c0 ea 8d bb 58 56>
6221929103415579899

Run in browser: (wrong result)

Uint8Array(9) [9, 251, 20, 192, 234, 141, 187, 88, 86]
6221929103415580000

Notice "9899" at tail was lost!

@dcodeIO
Copy link
Member

dcodeIO commented Apr 12, 2017

Is dec.value a number or a Long? This usually happens when long.js is not properly recognized.

In case of doubt, try the following before decoding anything:

var Long = ...;
protobuf.util.Long = Long;
protobuf.configure();

@k8w
Copy link
Author

k8w commented Apr 12, 2017

@dcodeIO in NodeJS, dec.value is Long, in browser it is number

@dcodeIO
Copy link
Member

dcodeIO commented Apr 12, 2017

Then long.js isn't present / recognized in your browser build and unsafe numbers are used (see long.js for more information on why precision loss is happening). Try assigning Long explicitly as shown above prior to decoding. More information on why this is happening is available here.

@k8w
Copy link
Author

k8w commented Apr 12, 2017

Okay.
6.5.3 works well.

@dcodeIO
Copy link
Member

dcodeIO commented Apr 12, 2017

That's strange. Basically, long.js is loaded automatically when a global require function is present, that has not been renamed, and the long module is available somewhere in the project.

@dcodeIO dcodeIO added unsure and removed invalid labels Apr 12, 2017
@k8w
Copy link
Author

k8w commented Apr 18, 2017

@dcodeIO
In 6.7.3 , it will ok if modify generated js like this:

var $protobuf = require("protobufjs/minimal");

//add this
var Long = require('long');
$protobuf.util.Long = Long;
$protobuf.configure();

@dcodeIO
Copy link
Member

dcodeIO commented Apr 19, 2017

You can do this in any other file as well, it's just important to do it once in your project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants