paritytech / paritytech/parity-scale-codec

Do not derive encode/decode when discriminant doesn't fit u8.

Open
#283 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
287
Forks
103
Avg merge
6d 13h
Merged PRs (30d)
1

Description

whe the discriminant doesn't fit u8 the derivation is wrong (more precisely: unexpected)

#[derive(Encode, Decode)]
#[repr(u32)]
enum ABC {
	D = 3u32,
}
#[repr(u32)]
enum ABC { D = 3u32, }
const _: () =
    {
        #[allow(unknown_lints)]
        #[allow(rust_2018_idioms)]
        extern crate parity_scale_codec as _parity_scale_codec;
        impl _parity_scale_codec::Encode for ABC {
            fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output +
                         ?Sized>(&self,
                                 __codec_dest_edqy: &mut __CodecOutputEdqy) {
                match *self {
                    ABC::D => {
                        __codec_dest_edqy.push_byte(3u32 as
                                                        ::core::primitive::u8);
                    }
                    _ => (),
                }
            }
        }
        impl _parity_scale_codec::EncodeLike for ABC { }
    };
const _: () =
    {
        #[allow(unknown_lints)]
        #[allow(rust_2018_idioms)]
        extern crate parity_scale_codec as _parity_scale_codec;
        impl _parity_scale_codec::Decode for ABC {
            fn decode<__CodecInputEdqy: _parity_scale_codec::Input>(__codec_input_edqy:
                                                                        &mut __CodecInputEdqy)
             -> ::core::result::Result<Self, _parity_scale_codec::Error> {
                match __codec_input_edqy.read_byte().map_err(|e|
                                                                 e.chain("Could not decode `ABC`, failed to read variant byte"))?
                    {
                    __codec_x_edqy if
                    __codec_x_edqy == 3u32 as ::core::primitive::u8 => {
                        ::core::result::Result::Ok(ABC::D)
                    }
                    _ =>
                    ::core::result::Result::Err("Could not decode `ABC`, variant doesn\'t exist".into()),
                }
            }
        }
    };

I think we can use From::from instead of as maybe but it is probably a breaking change.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by inspecting the Encode and Decode derive expansion for the repr(u32) enum shown in the issue, especially the generated casts to u8. Compare the generated behavior with the discriminant's declared representation and determine the intended handling when it does not fit; done means the derivation no longer produces the unexpected encoding and its compatibility impact is addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.