Skip to content

Commit 0a66e7f

Browse files
committed
Stop trying to decode blobs as UTF8 strings
1 parent f1749fe commit 0a66e7f

File tree

4 files changed

+45
-9
lines changed

4 files changed

+45
-9
lines changed

lib/src/blob.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Blob {
2727
if (_string != null) {
2828
return _string;
2929
}
30-
return UTF8.decode(_codeUnits);
30+
return UTF8.decode(_codeUnits, allowMalformed: true);
3131
}
3232

3333
/// Returns the value of the blob as a list of code units.
@@ -43,7 +43,7 @@ class Blob {
4343
if (_string != null) {
4444
_hashcode = _string.hashCode;
4545
} else {
46-
_hashcode = UTF8.decode(_codeUnits).hashCode;
46+
_hashcode = UTF8.decode(_codeUnits, allowMalformed: true).hashCode;
4747
}
4848
}
4949
return _hashcode;

lib/src/query/standard_data_packet.dart

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@ class _StandardDataPacket extends Row {
55
final Map<Symbol, int> _fieldIndex;
66

77
_StandardDataPacket(Buffer buffer, List<_FieldImpl> fieldPackets, this._fieldIndex) :
8-
values = new List<dynamic>(fieldPackets.length) {
8+
values = new List<dynamic>(fieldPackets.length) {
99
for (var i = 0; i < fieldPackets.length; i++) {
1010

11-
var s;
1211
var list;
1312
int length = buffer.readLengthCodedBinary();
1413
if (length != null) {
1514
list = buffer.readList(length);
16-
s = UTF8.decode(list);
17-
}
18-
19-
if (s == null) {
15+
} else {
2016
values[i] = null;
2117
continue;
2218
}
@@ -26,11 +22,13 @@ class _StandardDataPacket extends Row {
2622
case FIELD_TYPE_INT24: // mediumint
2723
case FIELD_TYPE_LONGLONG: // bigint/serial
2824
case FIELD_TYPE_LONG: // int
25+
var s = UTF8.decode(list);
2926
values[i] = int.parse(s);
3027
break;
3128
case FIELD_TYPE_NEWDECIMAL: // decimal
3229
case FIELD_TYPE_FLOAT: // float
3330
case FIELD_TYPE_DOUBLE: // double
31+
var s = UTF8.decode(list);
3432
values[i] = double.parse(s);
3533
break;
3634
case FIELD_TYPE_BIT: // bit
@@ -43,25 +41,30 @@ class _StandardDataPacket extends Row {
4341
case FIELD_TYPE_DATE: // date
4442
case FIELD_TYPE_DATETIME: // datetime
4543
case FIELD_TYPE_TIMESTAMP: // timestamp
44+
var s = UTF8.decode(list);
4645
values[i] = DateTime.parse(s);
4746
break;
4847
case FIELD_TYPE_TIME: // time
48+
var s = UTF8.decode(list);
4949
var parts = s.split(":");
5050
values[i] = new Duration(days: 0, hours: int.parse(parts[0]),
5151
minutes: int.parse(parts[1]), seconds: int.parse(parts[2]),
5252
milliseconds: 0);
5353
break;
5454
case FIELD_TYPE_YEAR: // year
55+
var s = UTF8.decode(list);
5556
values[i] = int.parse(s);
5657
break;
5758
case FIELD_TYPE_STRING: // char/binary/enum/set
5859
case FIELD_TYPE_VAR_STRING: // varchar/varbinary
60+
var s = UTF8.decode(list);
5961
values[i] = s;
6062
break;
6163
case FIELD_TYPE_BLOB: // tinytext/text/mediumtext/longtext/tinyblob/mediumblob/blob/longblob
62-
values[i] = new Blob.fromString(s);
64+
values[i] = new Blob.fromBytes(list);
6365
break;
6466
case FIELD_TYPE_GEOMETRY: // geometry
67+
var s = UTF8.decode(list);
6568
values[i] = s;
6669
break;
6770
}

test/integration/blob.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
part of integrationtests;
2+
3+
void runBlobTests(String user, String password, String db, int port, String host) {
4+
ConnectionPool pool;
5+
group('charset tests:', () {
6+
test('setup', () {
7+
pool = new ConnectionPool(user:user, password:password, db:db, port:port, host:host, max:1);
8+
return setup(pool, "blobtest", "create table blobtest (stuff blob)");
9+
});
10+
11+
test('write blob', () async {
12+
var query = await pool.prepare("insert into blobtest (stuff) values (?)");
13+
await query.execute([[0xc3, 0x28]]); // this is an invalid UTF8 string
14+
});
15+
16+
test('read data', () async {
17+
var c = new Completer();
18+
var results = await pool.query('select * from blobtest');
19+
results.listen((row) {
20+
expect((row[0] as Blob).toBytes(), equals([0xc3, 0x28]));
21+
}, onDone: () {
22+
c.complete();
23+
});
24+
return c.future;
25+
});
26+
27+
test('close connection', () {
28+
pool.closeConnectionsWhenNotInUse();
29+
});
30+
});
31+
}

test/integration_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ part 'integration/errors.dart';
2323
part 'integration/stored_procedures.dart';
2424
part 'integration/execute_multi.dart';
2525
part 'integration/prepared_query.dart';
26+
part 'integration/blob.dart';
2627

2728
void main(List<String> args) {
2829
hierarchicalLoggingEnabled = true;
@@ -61,6 +62,7 @@ void main(List<String> args) {
6162
runStreamTests(user, password, db, port, host);
6263
runRowTests(user, password, db, port, host);
6364
runErrorTests(user, password, db, port, host);
65+
runBlobTests(user, password, db, port, host);
6466
// runStoredProcedureTests(user, password, db, port, host);
6567
runExecuteMultiTests(user, password, db, port, host);
6668
// if (results['large_packets'] == 'true') {

0 commit comments

Comments
 (0)