Fix JSON serialization of unsigned 64-bit fields. (#229)
Fix JSON serialization of unsigned 64-bit fields.
The current behavior treats signed and unsigned 64-bit fields the same, which relies on users needing to know to flip the negative appropriately. With the introduction of toStringUnsigned in fixnum v 0.10.9, we can handle this correctly.
diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index 26131fb..74b26e5 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.13.8
+
+* Fix JSON serialization of unsigned 64-bit fields.
+
## 0.13.7
* Override `operator ==` and `hashCode` in `PbMap` so that two `PbMap`s are equal if they have equal key/value pairs.
diff --git a/protobuf/lib/src/protobuf/json.dart b/protobuf/lib/src/protobuf/json.dart
index f665608..23eb4fb 100644
--- a/protobuf/lib/src/protobuf/json.dart
+++ b/protobuf/lib/src/protobuf/json.dart
@@ -30,10 +30,11 @@
return fieldValue.value; // assume |value| < 2^52
case PbFieldType._INT64_BIT:
case PbFieldType._SINT64_BIT:
- case PbFieldType._UINT64_BIT:
- case PbFieldType._FIXED64_BIT:
case PbFieldType._SFIXED64_BIT:
return fieldValue.toString();
+ case PbFieldType._UINT64_BIT:
+ case PbFieldType._FIXED64_BIT:
+ return fieldValue.toStringUnsigned();
case PbFieldType._GROUP_BIT:
case PbFieldType._MESSAGE_BIT:
return fieldValue.writeToJsonMap();
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index 63f0a13..26678f2 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
name: protobuf
-version: 0.13.7
+version: 0.13.8
author: Dart Team <misc@dartlang.org>
description: >
Runtime library for protocol buffers support.
@@ -8,7 +8,7 @@
environment:
sdk: '>=2.0.0-dev.17.0 <3.0.0'
dependencies:
- fixnum: '>=0.9.0 <0.11.0'
+ fixnum: ^0.10.9
dev_dependencies:
test: '>=1.2.0'
benchmark_harness: any
diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml
index c3ec0d3..9adcaf4 100644
--- a/protoc_plugin/pubspec.yaml
+++ b/protoc_plugin/pubspec.yaml
@@ -1,5 +1,5 @@
name: protoc_plugin
-version: 16.0.4
+version: 16.0.4-dev-1
author: Dart Team <misc@dartlang.org>
description: Protoc compiler plugin to generate Dart code
homepage: https://github.com/dart-lang/protobuf
@@ -8,9 +8,9 @@
sdk: '>=2.0.0 <3.0.0'
dependencies:
- fixnum: ^0.10.5
+ fixnum: ^0.10.9
path: ^1.0.0
- protobuf: ^0.13.7
+ protobuf: ^0.13.8
dart_style: ^1.0.6
dev_dependencies:
diff --git a/protoc_plugin/test/json_test.dart b/protoc_plugin/test/json_test.dart
index 98b46e6..1ed35f6 100755
--- a/protoc_plugin/test/json_test.dart
+++ b/protoc_plugin/test/json_test.dart
@@ -5,6 +5,7 @@
library json_test;
+import 'package:fixnum/fixnum.dart';
import 'package:protobuf/protobuf.dart';
import 'package:test/test.dart';
@@ -39,6 +40,20 @@
(message) => message.writeToJson() == expectedJson, 'Incorrect output');
}
+ test('testUnsignedOutput', () {
+ TestAllTypes message = TestAllTypes();
+ // These values selected because:
+ // (1) large enough to set the sign bit
+ // (2) don't set all of the first 10 bits under the sign bit
+ // (3) are near each other
+ message.optionalUint64 = Int64.parseHex("f0000000ffff0000");
+ message.optionalFixed64 = Int64.parseHex("f0000000ffff0001");
+
+ String expectedJsonValue =
+ '{"4":"17293822573397606400","8":"17293822573397606401"}';
+ expect(message.writeToJson(), expectedJsonValue);
+ });
+
test('testOutput', () {
expect(getAllSet().writeToJson(), TEST_ALL_TYPES_JSON);
@@ -105,6 +120,26 @@
expect(optionalBytes(':"MTE2",', ':"YQ==",'), 'a');
});
+ test('testParseUnsigned', () {
+ TestAllTypes parsed = TestAllTypes.fromJson(
+ '{"4":"17293822573397606400","8":"17293822573397606401"}');
+ TestAllTypes expected = TestAllTypes();
+ expected.optionalUint64 = Int64.parseHex("f0000000ffff0000");
+ expected.optionalFixed64 = Int64.parseHex("f0000000ffff0001");
+
+ expect(parsed, expected);
+ });
+
+ test('testParseUnsignedLegacy', () {
+ TestAllTypes parsed = TestAllTypes.fromJson(
+ '{"4":"-1152921500311945216","8":"-1152921500311945215"}');
+ TestAllTypes expected = TestAllTypes();
+ expected.optionalUint64 = Int64.parseHex("f0000000ffff0000");
+ expected.optionalFixed64 = Int64.parseHex("f0000000ffff0001");
+
+ expect(parsed, expected);
+ });
+
test('testParse', () {
expect(TestAllTypes.fromJson(TEST_ALL_TYPES_JSON), getAllSet());
});