Skip to content

Commit 479dfdc

Browse files
authored
fix: Treat fixed64 as unsigned in converters (#2266)
1 parent e30c334 commit 479dfdc

8 files changed

Lines changed: 108 additions & 16 deletions

File tree

cli/targets/static.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ function buildType(ref, type) {
474474
+ JSON.stringify(field.typeDefault.low) + ","
475475
+ JSON.stringify(field.typeDefault.high) + ","
476476
+ JSON.stringify(field.typeDefault.unsigned)
477-
+ ") : " + field.typeDefault.toNumber(field.type.charAt(0) === "u") + ";");
477+
+ ") : " + field.typeDefault.toNumber(field.type === "uint64" || field.type === "fixed64") + ";");
478478
else if (field.bytes) {
479479
push(escapeName(type.name) + ".prototype" + prop + " = $util.newBuffer(" + JSON.stringify(Array.prototype.slice.call(field.typeDefault)) + ");");
480480
} else

src/converter.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
6161
("m%s=d%s|0", prop, prop);
6262
break;
6363
case "uint64":
64+
case "fixed64":
6465
isUnsigned = true;
6566
// eslint-disable-next-line no-fallthrough
6667
case "int64":
6768
case "sint64":
68-
case "fixed64":
6969
case "sfixed64": gen
7070
("if(util.Long)")
71-
("(m%s=util.Long.fromValue(d%s)).unsigned=%j", prop, prop, isUnsigned)
71+
("m%s=util.Long.fromValue(d%s,%j)", prop, prop, isUnsigned)
7272
("else if(typeof d%s===\"string\")", prop)
7373
("m%s=parseInt(d%s,10)", prop, prop)
7474
("else if(typeof d%s===\"number\")", prop)
@@ -181,11 +181,11 @@ function genValuePartial_toObject(gen, field, fieldIndex, prop) {
181181
("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s", prop, prop, prop, prop);
182182
break;
183183
case "uint64":
184+
case "fixed64":
184185
isUnsigned = true;
185186
// eslint-disable-next-line no-fallthrough
186187
case "int64":
187188
case "sint64":
188-
case "fixed64":
189189
case "sfixed64": gen
190190
("if(typeof BigInt!==\"undefined\"&&o.longs===BigInt)")
191191
("d%s=typeof m%s===\"number\"?BigInt(m%s):util.Long.fromBits(m%s.low>>>0,m%s.high>>>0,%j).toBigInt()", prop, prop, prop, prop, prop, isUnsigned)

src/field.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ Field.prototype.resolve = function resolve() {
328328

329329
// convert to internal data type if necesssary
330330
if (this.long) {
331-
this.typeDefault = util.Long.fromNumber(this.typeDefault, this.type.charAt(0) === "u");
331+
this.typeDefault = util.Long.fromNumber(this.typeDefault, this.type === "uint64" || this.type === "fixed64");
332332

333333
/* istanbul ignore else */
334334
if (Object.freeze)

tests/api_converters.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,55 @@ tape.test("converters", function(test) {
241241
test.end();
242242
});
243243

244+
test.test(test.name + " - fixed64 signedness", function(test) {
245+
var root = protobuf.Root.fromJSON({
246+
nested: {
247+
Fixed: {
248+
fields: {
249+
fixed64Val: {
250+
type: "fixed64",
251+
id: 1
252+
},
253+
sfixed64Val: {
254+
type: "sfixed64",
255+
id: 2
256+
}
257+
}
258+
}
259+
}
260+
});
261+
var Fixed = root.lookupType("Fixed");
262+
var msg = Fixed.fromObject({
263+
fixed64Val: "11000000000000000001",
264+
sfixed64Val: "-9000000000000000001"
265+
});
266+
var msgFromNumber = Fixed.fromObject({
267+
fixed64Val: 11000000000000000000,
268+
sfixed64Val: -9000000000000000000
269+
});
270+
var msgFromLongZero = Fixed.fromObject({
271+
fixed64Val: protobuf.util.Long.ZERO,
272+
sfixed64Val: protobuf.util.Long.UZERO
273+
});
274+
var obj = Fixed.toObject(msg, { longs: BigInt });
275+
var defaults = Fixed.toObject(Fixed.create(), { defaults: true });
276+
277+
test.equal(msg.fixed64Val.unsigned, true, "should set fixed64 values as unsigned");
278+
test.equal(msg.sfixed64Val.unsigned, false, "should set sfixed64 values as signed");
279+
test.same(msgFromNumber.fixed64Val, protobuf.util.Long.fromString("11000000000000000000", true), "should set fixed64 values from numbers as unsigned");
280+
test.same(msgFromNumber.sfixed64Val, protobuf.util.Long.fromString("-9000000000000000000"), "should set sfixed64 values from numbers as signed");
281+
test.same(msgFromLongZero.fixed64Val, protobuf.util.Long.UZERO, "should set fixed64 values from Longs as unsigned");
282+
test.same(msgFromLongZero.sfixed64Val, protobuf.util.Long.ZERO, "should set sfixed64 values from Longs as signed");
283+
test.equal(protobuf.util.Long.ZERO.unsigned, false, "should not mutate Long.ZERO");
284+
test.equal(protobuf.util.Long.UZERO.unsigned, true, "should not mutate Long.UZERO");
285+
test.equal(obj.fixed64Val, 11000000000000000001n, "should output fixed64 as unsigned bigint");
286+
test.equal(obj.sfixed64Val, -9000000000000000001n, "should output sfixed64 as signed bigint");
287+
test.same(defaults.fixed64Val, { low: 0, high: 0, unsigned: true }, "should default fixed64 as unsigned");
288+
test.same(defaults.sfixed64Val, { low: 0, high: 0, unsigned: false }, "should default sfixed64 as signed");
289+
290+
test.end();
291+
});
292+
244293
test.test(test.name + " - Message#toJSON", function(test) {
245294
var msg = Message.create();
246295
msg.$type = {

tests/cli.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,49 @@ tape.test("pbjs generates static code", function(test) {
9595
});
9696
});
9797

98+
tape.test("pbjs generates unsigned fixed64 defaults", function(test) {
99+
cliTest(test, function() {
100+
var root = protobuf.Root.fromJSON({
101+
nested: {
102+
M: {
103+
fields: {
104+
v: {
105+
type: "fixed64",
106+
id: 1,
107+
options: {
108+
default: "11000000000000000001"
109+
}
110+
},
111+
s: {
112+
type: "sfixed64",
113+
id: 2,
114+
options: {
115+
default: "-9000000000000000001"
116+
}
117+
}
118+
}
119+
}
120+
}
121+
});
122+
root.resolveAll();
123+
124+
var staticTarget = require("../cli/targets/static");
125+
126+
staticTarget(root, {}, function(err, jsCode) {
127+
test.error(err, "static code generation worked");
128+
test.ok(
129+
/M\.prototype\.v = \$util\.Long \? \$util\.Long\.fromBits\([^)]*,true\) : 11000000000000000000;/.test(jsCode),
130+
"fixed64 default is emitted as unsigned"
131+
);
132+
test.ok(
133+
/M\.prototype\.s = \$util\.Long \? \$util\.Long\.fromBits\([^)]*,false\) : -9000000000000000000;/.test(jsCode),
134+
"sfixed64 default is emitted as signed"
135+
);
136+
test.end();
137+
});
138+
});
139+
});
140+
98141
tape.test("pbts passes jsdoc arguments without a shell", function(test) {
99142
var pbts = require("../cli/pbts");
100143
var originalSpawn = child_process.spawn;

tests/data/convert.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ $root.Message = (function() {
413413
}
414414
if (object.uint64Val != null)
415415
if ($util.Long)
416-
(message.uint64Val = $util.Long.fromValue(object.uint64Val)).unsigned = true;
416+
message.uint64Val = $util.Long.fromValue(object.uint64Val, true);
417417
else if (typeof object.uint64Val === "string")
418418
message.uint64Val = parseInt(object.uint64Val, 10);
419419
else if (typeof object.uint64Val === "number")
@@ -426,7 +426,7 @@ $root.Message = (function() {
426426
message.uint64Repeated = [];
427427
for (var i = 0; i < object.uint64Repeated.length; ++i)
428428
if ($util.Long)
429-
(message.uint64Repeated[i] = $util.Long.fromValue(object.uint64Repeated[i])).unsigned = true;
429+
message.uint64Repeated[i] = $util.Long.fromValue(object.uint64Repeated[i], true);
430430
else if (typeof object.uint64Repeated[i] === "string")
431431
message.uint64Repeated[i] = parseInt(object.uint64Repeated[i], 10);
432432
else if (typeof object.uint64Repeated[i] === "number")
@@ -494,7 +494,7 @@ $root.Message = (function() {
494494
if (keys[i] === "__proto__")
495495
$util.makeProp(message.int64Map, keys[i]);
496496
if ($util.Long)
497-
(message.int64Map[keys[i]] = $util.Long.fromValue(object.int64Map[keys[i]])).unsigned = false;
497+
message.int64Map[keys[i]] = $util.Long.fromValue(object.int64Map[keys[i]], false);
498498
else if (typeof object.int64Map[keys[i]] === "string")
499499
message.int64Map[keys[i]] = parseInt(object.int64Map[keys[i]], 10);
500500
else if (typeof object.int64Map[keys[i]] === "number")

tests/data/mapbox/vector_tile.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ $root.vector_tile = (function() {
550550
message.doubleValue = Number(object.doubleValue);
551551
if (object.intValue != null)
552552
if ($util.Long)
553-
(message.intValue = $util.Long.fromValue(object.intValue)).unsigned = false;
553+
message.intValue = $util.Long.fromValue(object.intValue, false);
554554
else if (typeof object.intValue === "string")
555555
message.intValue = parseInt(object.intValue, 10);
556556
else if (typeof object.intValue === "number")
@@ -559,7 +559,7 @@ $root.vector_tile = (function() {
559559
message.intValue = new $util.LongBits(object.intValue.low >>> 0, object.intValue.high >>> 0).toNumber();
560560
if (object.uintValue != null)
561561
if ($util.Long)
562-
(message.uintValue = $util.Long.fromValue(object.uintValue)).unsigned = true;
562+
message.uintValue = $util.Long.fromValue(object.uintValue, true);
563563
else if (typeof object.uintValue === "string")
564564
message.uintValue = parseInt(object.uintValue, 10);
565565
else if (typeof object.uintValue === "number")
@@ -568,7 +568,7 @@ $root.vector_tile = (function() {
568568
message.uintValue = new $util.LongBits(object.uintValue.low >>> 0, object.uintValue.high >>> 0).toNumber(true);
569569
if (object.sintValue != null)
570570
if ($util.Long)
571-
(message.sintValue = $util.Long.fromValue(object.sintValue)).unsigned = false;
571+
message.sintValue = $util.Long.fromValue(object.sintValue, false);
572572
else if (typeof object.sintValue === "string")
573573
message.sintValue = parseInt(object.sintValue, 10);
574574
else if (typeof object.sintValue === "number")
@@ -933,7 +933,7 @@ $root.vector_tile = (function() {
933933
var message = new $root.vector_tile.Tile.Feature();
934934
if (object.id != null)
935935
if ($util.Long)
936-
(message.id = $util.Long.fromValue(object.id)).unsigned = true;
936+
message.id = $util.Long.fromValue(object.id, true);
937937
else if (typeof object.id === "string")
938938
message.id = parseInt(object.id, 10);
939939
else if (typeof object.id === "number")

tests/data/test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3965,7 +3965,7 @@ $root.jspb = (function() {
39653965
message.boolField = Boolean(object.boolField);
39663966
if (object.intField != null)
39673967
if ($util.Long)
3968-
(message.intField = $util.Long.fromValue(object.intField)).unsigned = false;
3968+
message.intField = $util.Long.fromValue(object.intField, false);
39693969
else if (typeof object.intField === "string")
39703970
message.intField = parseInt(object.intField, 10);
39713971
else if (typeof object.intField === "number")
@@ -9082,7 +9082,7 @@ $root.jspb = (function() {
90829082
if (keys[i] === "__proto__")
90839083
$util.makeProp(message.mapStringInt64, keys[i]);
90849084
if ($util.Long)
9085-
(message.mapStringInt64[keys[i]] = $util.Long.fromValue(object.mapStringInt64[keys[i]])).unsigned = false;
9085+
message.mapStringInt64[keys[i]] = $util.Long.fromValue(object.mapStringInt64[keys[i]], false);
90869086
else if (typeof object.mapStringInt64[keys[i]] === "string")
90879087
message.mapStringInt64[keys[i]] = parseInt(object.mapStringInt64[keys[i]], 10);
90889088
else if (typeof object.mapStringInt64[keys[i]] === "number")
@@ -20156,7 +20156,7 @@ $root.google = (function() {
2015620156
message.identifierValue = String(object.identifierValue);
2015720157
if (object.positiveIntValue != null)
2015820158
if ($util.Long)
20159-
(message.positiveIntValue = $util.Long.fromValue(object.positiveIntValue)).unsigned = true;
20159+
message.positiveIntValue = $util.Long.fromValue(object.positiveIntValue, true);
2016020160
else if (typeof object.positiveIntValue === "string")
2016120161
message.positiveIntValue = parseInt(object.positiveIntValue, 10);
2016220162
else if (typeof object.positiveIntValue === "number")
@@ -20165,7 +20165,7 @@ $root.google = (function() {
2016520165
message.positiveIntValue = new $util.LongBits(object.positiveIntValue.low >>> 0, object.positiveIntValue.high >>> 0).toNumber(true);
2016620166
if (object.negativeIntValue != null)
2016720167
if ($util.Long)
20168-
(message.negativeIntValue = $util.Long.fromValue(object.negativeIntValue)).unsigned = false;
20168+
message.negativeIntValue = $util.Long.fromValue(object.negativeIntValue, false);
2016920169
else if (typeof object.negativeIntValue === "string")
2017020170
message.negativeIntValue = parseInt(object.negativeIntValue, 10);
2017120171
else if (typeof object.negativeIntValue === "number")

0 commit comments

Comments
 (0)