protobuf.js使用uint64类型超过16位长度decode的bug

it2025-01-13  6

protobuf.js使用uint64类型超过16位长度decode的bug

原版在这里:

https://www.npmjs.com/package/protobufjs

 

protobuf-library.js里有个LongBits的原型toNumber是这样写的:

LongBits.prototype.toNumber = function toNumber(unsigned) { if (!unsigned && this.hi >>> 31) { var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; if (!lo) hi = hi + 1 >>> 0; return -(lo + hi * 4294967296); } return this.lo + this.hi * 4294967296; };

我一步步查到

this.lo + this.hi * 4294967296;

的时候发现精度有问题

搜了好久发现了一个BigInt解决这个问题

修改后如下:

LongBits.prototype.toNumber = function toNumber(unsigned) { if (!unsigned && this.hi >>> 31) { var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; if (!lo) hi = hi + 1 >>> 0; return -(lo + hi * 4294967296); } return (BigInt(this.lo) + BigInt(this.hi * 4294967296)).toString(); };

proto_bundle.min文件搜索

this.lo+4294967296*this.hi

进行替换

(BigInt(this.lo)+BigInt(4294967296*this.hi)).toString()

 

protobuf-library.min文件搜

this.lo+this.hi*4294967296

进行替换

(BigInt(this.lo)+BigInt(this.hi*4294967296)).toString()

 

 

解决方案2:

protobuf-library.js开头引用

let bigIntXXX; if(!window.bigInt) { bigIntXXX = require("./BigInteger.js"); } else { bigIntXXX = bigInt; }

 

LongBits.prototype.toNumber修改为

LongBits.prototype.toNumber = function toNumber(unsigned) { if (!unsigned && this.hi >>> 31) { var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; if (!lo) hi = hi + 1 >>> 0; return -(lo + hi * 4294967296); } let xxx = bigIntXXX(this.lo.toString()).add(bigIntXXX(this.hi.toString()).multiply(4294967296)); return xxx.toString(); };

 

 

最新回复(0)