shamblett / cbor

A CBOR implementation for Dart
MIT License
36 stars 15 forks source link

How does toJson decode Bytes List? #47

Closed slice-mohit closed 1 year ago

slice-mohit commented 1 year ago

I have a cbor data. On printing CborValue with cborDecode, I'm getting this

cbor ```bash [166, 101, 112, 114, 111, 116, 111, 1, 99, 118, 101, 114, 101, 49, 46, 48, 46, 51, 101, 98, 105, 114, 116, 104, 26, 0, 10, 174, 97, 102, 112, 117, 98, 107, 101, 121, 88, 33, 3, 50, 131, 14, 50, 9, 233, 80, 149, 122, 211, 150, 76, 34, 63, 136, 248, 223, 97, 218, 210, 247, 22, 8, 127, 92, 51, 109, 166, 51, 114, 165, 110, 106, 99, 97, 114, 100, 95, 110, 111, 110, 99, 101, 80, 204, 191, 224, 231, 61, 126, 115, 32, 173, 10, 117, 112, 3, 36, 30, 117, 101, 115, 108, 111, 116, 115, 130, 0, 10] ```
{proto: 1, ver: 1.0.3, birth: 700001, pubkey: [3, 50, 131, 14, 50, 9, 233, 80, 149, 122, 211, 150, 76, 34, 63, 136, 248, 223, 97, 218, 210, 247, 22, 8, 127, 92, 51, 109, 166, 51, 114, 165, 110], card_nonce: [204, 191, 224, 231, 61, 126, 115, 32, 173, 10, 117, 112, 3, 36, 30, 117], slots: [0, 10]}

but .toJson prints

{proto: 1, ver: 1.0.3, birth: 700001, pubkey: AzKDDjIJ6VCVetOWTCI_iPjfYdrS9xYIf1wzbaYzcqVu, card_nonce: zL_g5z1-cyCtCnVwAyQedQ, slots: [0, 10]}

How does the bytes list map to this string value? As far as I can see, the string in pubkey and card_nonce are neither UTF equivalent nor ASCII. How does toJson convert the following bytes to string?

shamblett commented 1 year ago

To answer your question the package eventually uses the standard Dart json convertor from the Dart Convert library package, strings are are assumed to be UTF8, however the package supports malformed UTF8 conversion if you allow, it will substitute valid replacement characters. There options you can set to control this, could you supply the code you are using to do this so I can better trace what is happening here.

slice-mohit commented 1 year ago

This is the minimal code

import 'dart:convert';

import 'package:cbor/cbor.dart';

void main() {
  final cborRaw = [166, 101, 112, 114, 111, 116, 111, 1, 99, 118, 101, 114, 101, 49, 46, 48, 46, 51, 101, 98, 105, 114, 116, 104, 26, 0, 10, 174, 97, 102, 112, 117, 98, 107, 101, 121, 88, 33, 3, 50, 131, 14, 50, 9, 233, 80, 149, 122, 211, 150, 76, 34, 63, 136, 248, 223, 97, 218, 210, 247, 22, 8, 127, 92, 51, 109, 166, 51, 114, 165, 110, 106, 99, 97, 114, 100, 95, 110, 111, 110, 99, 101, 80, 204, 191, 224, 231, 61, 126, 115, 32, 173, 10, 117, 112, 3, 36, 30, 117, 101, 115, 108, 111, 116, 115, 130, 0, 10] ; 
  final cborDecoded = cbor.decode(cborRaw);

  print(cborDecoded);
  print(cborDecoded.toJson());
}

The output is:

{proto: 1, ver: 1.0.3, birth: 700001, pubkey: [3, 50, 131, 14, 50, 9, 233, 80, 149, 122, 211, 150, 76, 34, 63, 136, 248, 223, 97, 218, 210, 247, 22, 8, 127, 92, 51, 109, 166, 51, 114, 165, 110], card_nonce: [204, 191, 224, 231, 61, 126, 115, 32, 173, 10, 117, 112, 3, 36, 30, 117], slots: [0, 10]}

{proto: 1, ver: 1.0.3, birth: 700001, pubkey: AzKDDjIJ6VCVetOWTCI_iPjfYdrS9xYIf1wzbaYzcqVu, card_nonce: zL_g5z1-cyCtCnVwAyQedQ, slots: [0, 10]}

Is the byte pubkey [3, 50, 131, 14, 50, 9, 233, 80, 149, 122, 211, 150, 76, 34, 63, 136, 248, 223, 97, 218, 210, 247, 22, 8, 127, 92, 51, 109, 166, 51, 114, 165, 110] UTF8 decoded to AzKDDjIJ6VCVetOWTCI_iPjfYdrS9xYIf1wzbaYzcqVu?

shamblett commented 1 year ago

OK, the pubkey and card_nonce bytes are actually being decoded as base64Url format, this is the tag value that the package defaults to if no tag value can be found in the CBOR data. You could try adding a tag value to indicate how you would like these fields to be converted in the toJson call, without some indication of how to decode these values the package of course won't know.

I'm not sure however why the default is base64URL, I'll look further at this.

slice-mohit commented 1 year ago

Yes, decoding with base64URL works.Thanks for helping out.