Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for tag 55799 self-describing CBOR #300

Closed
philandstuff opened this issue May 31, 2019 · 11 comments
Closed

Support for tag 55799 self-describing CBOR #300

philandstuff opened this issue May 31, 2019 · 11 comments

Comments

@philandstuff
Copy link

CBOR defines a self-describing tag which can be added to any item in a CBOR stream. It has no semantic meaning on the content:

It does not impart any
special semantics on the data item that follows; that is, the
semantics of a data item tagged with tag 55799 is exactly identical
to the semantics of the data item itself.

I therefore want to be able to decode some CBOR, but silently strip all 55799 tags as I encounter them.

CborHandle.SetInterfaceExt() seems like the right place, except that a) I don't want to add 55799 tags when I encode, and b) I want to be able to strip a 55799 tag in any location, on any item encoding any type. But adding a handler for interface{} seems like it breaks too many assumptions.

Is it possible to a) achieve this using existing codec features? or b) allow codec to (optionally) silently strip all 55799 tags when decoding?

(For context, my use case is implementing a Dhall library; it has defined CBOR semantics here, including the possibility of tag 55799 appearing anywhere.)

@philandstuff
Copy link
Author

Reading back my own issue, I realise it may not be clear what I'm asking for. Specifically:

  • I want to decode any item tagged with 55799 in the same way as decoding the underlying item
  • I do not want my encoded output to have tag 55799 in it

There are two difficulties I find here:

  1. codec seems to require symmetry between encoding and decoding, while I have an explicit requirement against this
  2. codec assumes that any tagged extension will be used by a single type, not by all types

@ugorji
Copy link
Owner

ugorji commented May 31, 2019

What I get from reading this and reading the section of the spec, is that, when decoding a supported cbor value, there is a chance for this tag to preceed it in the stream. If we see it, skip it?

@philandstuff
Copy link
Author

Yes, that’s my understanding of tag 55799.

@ugorji
Copy link
Owner

ugorji commented May 31, 2019

How soon do you need this?

@philandstuff
Copy link
Author

I have no particular timescale on this. It will help dhall-golang implement a small corner of the dhall-lang spec, but it’s not blocking anything more concrete than that right now.

@ugorji
Copy link
Owner

ugorji commented Jun 1, 2019

I re-read the spec. 2.4 Optional tagging says that a decoder should skip any tags it doesn't understand. Supporting that will ultimately fix this issue as an side effect.

Let me know if you think otherwise. That's the direction I'm currently working towards.

@philandstuff
Copy link
Author

I'd be happy with that as a solution, sure!

Thank you so much for your quick response on this. It far exceeded my expectations 😄 As I said before, I have no rush on this, so don't prioritise this work on my account.

In the meantime I'm able to work around with judicious use of a function like this:

func unwrap(i interface{}) interface{} {
	if val, ok := i.(codec.RawExt); ok {
		if val.Tag == 55799 {
			return unwrap(val.Value)
		}
	}
	return i
}

... and calling it from within my CodecDecodeSelf function.

@ugorji
Copy link
Owner

ugorji commented Jun 2, 2019

That's an ingenious way to workaround it. Nice!

@ugorji ugorji closed this as completed in b7b8e1c Jun 2, 2019
@philandstuff
Copy link
Author

I'm afraid b7b8e1c doesn't fix my issue for me. To take a concrete example, when I try to decode the following (in CBOR pretty form):

d9 d9f7     # tag(55799)
   82       # array(2)
      61    # text(1)
         78 # "x"
      00    # unsigned(0)

into an interface{} variable, using a CborHandle with SkipUnexpectedTags = true, I expect to get the value:

[]interface {}{"x", 0x0}

(ie, the value with the tag stripped), but instead i get:

""

I made a gist to demostrate what I see. Clone it, run go build and run the binary to see the output.

@ugorji
Copy link
Owner

ugorji commented Jun 3, 2019

Thanks.

Reviewing now - fix coming.

@ugorji ugorji reopened this Jun 3, 2019
@ugorji ugorji closed this as completed in a2c9fa2 Jun 3, 2019
@philandstuff
Copy link
Author

Thanks for the fix! I can confirm it works for me 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants