blob: e68d01a0543f8e4cb06c444db4cc4774e8631da8 [file] [log] [blame]
Anton Muhind6b19232013-07-10 20:39:25 +04001#!/usr/bin/env dart
2// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
3// for details. All rights reserved. Use of this source code is governed by a
4// BSD-style license that can be found in the LICENSE file.
5
Martin Kustermannc6cae3d2015-01-30 11:26:48 +01006import 'dart:typed_data';
7
Anton Muhind6b19232013-07-10 20:39:25 +04008import 'package:protobuf/protobuf.dart';
Brian Slesinsky5c8bba62015-07-10 14:28:29 -07009import 'package:test/test.dart';
Anton Muhind6b19232013-07-10 20:39:25 +040010
Anton Muhina58efc82013-07-10 22:02:13 +040011import 'test_util.dart';
12
Anton Muhind6b19232013-07-10 20:39:25 +040013void main() {
14 final throwsInvalidProtocolBufferException =
Diego Ballesteros Villamizar4ce027a2019-03-29 12:48:39 +010015 throwsA(TypeMatcher<InvalidProtocolBufferException>());
Anton Muhind6b19232013-07-10 20:39:25 +040016
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010017 group('testCodedBufferReader', () {
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020018 final inputBuffer = List<int>.unmodifiable([
Anton Muhind6b19232013-07-10 20:39:25 +040019 0xb8, 0x06, 0x20, // 103 int32 = 32
20 0xc0, 0x06, 0x40, // 104 int64 = 64
21 0xc8, 0x06, 0x20, // 105 uint32 = 32
22 0xd0, 0x06, 0x40, // 106 uint64 = 64
23 0xd8, 0x06, 0x40, // 107 sint32 = 32
24 0xe0, 0x06, 0x80, 0x01, // 108 sint64 = 64
25 0xed, 0x06, 0x20, 0x00, 0x00, 0x00, // 109 fixed32 = 32
26 0xf1, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
Jakob Andersen506c7062017-07-05 14:40:58 +020027 0x00, 0x00, // 110 fixed64 = 64
Anton Muhind6b19232013-07-10 20:39:25 +040028 0xfd, 0x06, 0x20, 0x00, 0x00, 0x00, // 111 sfixed32 = 64
29 0x81, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jakob Andersen506c7062017-07-05 14:40:58 +020030 0x00, // 112 sfixed64 = 64
Anton Muhind6b19232013-07-10 20:39:25 +040031 0x88, 0x07, 0x01, // 113 bool = true
32 0x92, 0x07, 0x0f, 0x6f, 0x70, 0x74, 0x69, 0x6f,
Jakob Andersen506c7062017-07-05 14:40:58 +020033 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x72,
34 0x69, 0x6e, 0x67, // 114 string 15 optional_string
Anton Muhind6b19232013-07-10 20:39:25 +040035 0x9a, 0x07, 0x0e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
Jakob Andersen506c7062017-07-05 14:40:58 +020036 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74,
37 0x65, 0x73 // 115 bytes 14 optional_bytes
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020038 ]);
Anton Muhind6b19232013-07-10 20:39:25 +040039
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +010040 void testWithList(List<int> inputBuffer) {
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020041 final cis = CodedBufferReader(inputBuffer);
Anton Muhind6b19232013-07-10 20:39:25 +040042
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010043 expect(cis.readTag(), makeTag(103, WIRETYPE_VARINT));
44 expect(cis.readInt32(), 32);
Anton Muhind6b19232013-07-10 20:39:25 +040045
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010046 expect(cis.readTag(), makeTag(104, WIRETYPE_VARINT));
47 expect(cis.readInt64(), expect64(64));
Anton Muhind6b19232013-07-10 20:39:25 +040048
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010049 expect(cis.readTag(), makeTag(105, WIRETYPE_VARINT));
50 expect(cis.readUint32(), 32);
Anton Muhind6b19232013-07-10 20:39:25 +040051
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010052 expect(cis.readTag(), makeTag(106, WIRETYPE_VARINT));
53 expect(cis.readUint64(), expect64(64));
Anton Muhind6b19232013-07-10 20:39:25 +040054
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010055 expect(cis.readTag(), makeTag(107, WIRETYPE_VARINT));
56 expect(cis.readSint32(), 32);
Anton Muhind6b19232013-07-10 20:39:25 +040057
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010058 expect(cis.readTag(), makeTag(108, WIRETYPE_VARINT));
59 expect(cis.readSint64(), expect64(64));
Anton Muhind6b19232013-07-10 20:39:25 +040060
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010061 expect(cis.readTag(), makeTag(109, WIRETYPE_FIXED32));
62 expect(cis.readFixed32(), 32);
Anton Muhind6b19232013-07-10 20:39:25 +040063
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010064 expect(cis.readTag(), makeTag(110, WIRETYPE_FIXED64));
65 expect(cis.readFixed64(), expect64(64));
Anton Muhind6b19232013-07-10 20:39:25 +040066
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010067 expect(cis.readTag(), makeTag(111, WIRETYPE_FIXED32));
68 expect(cis.readSfixed32(), 32);
Anton Muhind6b19232013-07-10 20:39:25 +040069
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010070 expect(cis.readTag(), makeTag(112, WIRETYPE_FIXED64));
71 expect(cis.readSfixed64(), expect64(64));
Anton Muhind6b19232013-07-10 20:39:25 +040072
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010073 expect(cis.readTag(), makeTag(113, WIRETYPE_VARINT));
74 expect(cis.readBool(), isTrue);
Anton Muhind6b19232013-07-10 20:39:25 +040075
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010076 expect(cis.readTag(), makeTag(114, WIRETYPE_LENGTH_DELIMITED));
77 expect(cis.readString(), 'optional_string');
78
79 expect(cis.readTag(), makeTag(115, WIRETYPE_LENGTH_DELIMITED));
80 expect(cis.readBytes(), 'optional_bytes'.codeUnits);
81 }
82
83 test('normal-list', () {
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020084 testWithList(Uint8List.fromList(inputBuffer));
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010085 });
86
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020087 test('unmodifiable-uint8-list-view', () {
88 testWithList(UnmodifiableUint8ListView(Uint8List.fromList(inputBuffer)));
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010089 });
90
91 test('uint8-list-view', () {
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020092 final uint8List = Uint8List(inputBuffer.length + 4);
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010093 uint8List[0] = 0xc0;
94 uint8List[1] = 0xc8;
95 uint8List.setRange(2, 2 + inputBuffer.length, inputBuffer);
96 uint8List[inputBuffer.length + 2] = 0xe0;
97 uint8List[inputBuffer.length + 3] = 0xed;
Sigurd Meldgaard9e3aa6b2019-07-09 12:08:56 +020098 final view = Uint8List.view(uint8List.buffer, 2, inputBuffer.length);
Martin Kustermannc6cae3d2015-01-30 11:26:48 +010099 testWithList(view);
100 });
Anton Muhind6b19232013-07-10 20:39:25 +0400101 });
102
103 test('testReadMaliciouslyLargeBlob', () {
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +0100104 var output = CodedBufferWriter();
Anton Muhind6b19232013-07-10 20:39:25 +0400105
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +0100106 var tag = makeTag(1, WIRETYPE_LENGTH_DELIMITED);
Anton Muhind6b19232013-07-10 20:39:25 +0400107 output.writeInt32NoTag(tag);
108 output.writeInt32NoTag(0x7FFFFFFF);
109 // Pad with a few random bytes.
110 output.writeInt32NoTag(0);
111 output.writeInt32NoTag(32);
112 output.writeInt32NoTag(47);
113
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +0100114 var input = CodedBufferReader(output.toBuffer());
Anton Muhind6b19232013-07-10 20:39:25 +0400115 expect(input.readTag(), tag);
116
Jakob Andersen506c7062017-07-05 14:40:58 +0200117 expect(() {
118 input.readBytes();
119 }, throwsInvalidProtocolBufferException);
Anton Muhind6b19232013-07-10 20:39:25 +0400120 });
121
Jakob Andersen5e7bb772017-08-14 14:00:31 +0200122 /// Tests that if we read a string that contains invalid UTF-8, no exception
123 /// is thrown. Instead, the invalid bytes are replaced with the Unicode
124 /// 'replacement character' U+FFFD.
Anton Muhind6b19232013-07-10 20:39:25 +0400125 test('testReadInvalidUtf8', () {
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +0100126 var input = CodedBufferReader([1, 0x80]);
127 var text = input.readString();
Anton Muhind6b19232013-07-10 20:39:25 +0400128 expect(text.codeUnitAt(0), 0xfffd);
129 });
130
131 test('testInvalidTag', () {
132 // Any tag number which corresponds to field number zero is invalid and
133 // should throw InvalidProtocolBufferException.
Ivan Inozemtsevcdffe5e2020-02-27 14:56:54 +0100134 for (var i = 0; i < 8; i++) {
Jakob Andersen506c7062017-07-05 14:40:58 +0200135 expect(() {
Diego Ballesteros Villamizar4ce027a2019-03-29 12:48:39 +0100136 CodedBufferReader([i]).readTag();
Jakob Andersen506c7062017-07-05 14:40:58 +0200137 }, throwsInvalidProtocolBufferException);
Anton Muhind6b19232013-07-10 20:39:25 +0400138 }
139 });
140}