Home > OS >  Strange decoding bug in Dart/Flutter with 'dart:convert'
Strange decoding bug in Dart/Flutter with 'dart:convert'

Time:07-21

Since I updated Flutter and all libraries, I encounter a strange bug when decoding a list of bytes.

The app communicates with a bluetooth device with flutter_blue library like that:

import 'dart:convert';

var result = await characteristic.read(); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
return utf8.decode(result, allowMalformed: true);

The decoded string is displayed in a widget. Previously, I had no problem, the string seems empty. But recently everything was updated, the string looks empty in the console but not in the widget since I see several empty squares as character. And the length of the string, even after the trim method, is 15, not 0.

I don't find any reason about this change on internet neither how to solve the problem.

Have you ever met this bug? Do you have a good solution?

Thanks

Edit: The result is the same with allowMalformed = true, of with

new String.fromCharCodes(result)

I think there is a bug with flutter when decoding only 0

CodePudding user response:

Char NUL (the 0) is an allowed character in UTF-8. It looks like the previous updates didn't implement the decoding right and ignored the NUL character. It should be expected that the NUL char is present in UTF-8 as a well-formed char.

The official docs also say:

If allowMalformed is true, the decoder replaces invalid (or unterminated) character sequences with the Unicode Replacement character U FFFD (�).

So, a solution for this problem is to parse the resulting string and check/replace the NUL chars and/or the Unicode Replacement chars.

CodePudding user response:

As editing in my question, it seems there is a problem with trailing zero.

From decimal to string, space equal to 32, and 0 is normally a empty character. But it's not anymore.

The solution I found is

var result = await characteristic.read();
var tempResult = List<int>.from(result);
tempResult.removeWhere((item) => item == 0);
return utf8.decode(tempResult, allowMalformed: true);

I copy the first list into a mutable list, and remove all 0 from it. That's work perfertly.

  • Related