-
Notifications
You must be signed in to change notification settings - Fork 5
round-trip encoding for extra zero bytes #13
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,7 @@ pub enum Value { | |||||||||||||||||||||
| pub struct Tlv { | ||||||||||||||||||||||
| tag: Tag, | ||||||||||||||||||||||
| val: Value, | ||||||||||||||||||||||
| leading_zeroes: usize, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| impl Tlv { | ||||||||||||||||||||||
|
|
@@ -45,7 +46,7 @@ impl Tlv { | |||||||||||||||||||||
| /// # assert_eq!(constructed_tlv.to_vec(), vec![0x21, 0x02, 0x01, 0x00]); | ||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||
| pub fn new(tag: Tag, value: Value) -> Result<Tlv> { | ||||||||||||||||||||||
| let mut tlv = Tlv { tag, val: value }; | ||||||||||||||||||||||
| let mut tlv = Tlv { tag, val: value, leading_zeroes: 0 }; | ||||||||||||||||||||||
| let is_tlv_primitive = tlv.is_primitive(); | ||||||||||||||||||||||
| tlv.val = match tlv.val { | ||||||||||||||||||||||
| Value::TlvList(list) => { | ||||||||||||||||||||||
|
|
@@ -140,12 +141,14 @@ impl Tlv { | |||||||||||||||||||||
| /// assert_eq!(tlv.to_vec(), vec![0x21, 0x08, 0x01, 0x02, 0xA1, 0xA2, 0x02, 0x02, 0xB1, 0xB2]); | ||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||
| pub fn to_vec(&self) -> Vec<u8> { | ||||||||||||||||||||||
| let mut out: Vec<u8> = (self.tag as u64) | ||||||||||||||||||||||
| let mut out: Vec<u8> = vec![0; self.leading_zeroes]; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| out.append(&mut (self.tag as u64) | ||||||||||||||||||||||
| .to_be_bytes() | ||||||||||||||||||||||
| .iter() | ||||||||||||||||||||||
| .skip_while(|&&x| x == 0) | ||||||||||||||||||||||
| .cloned() | ||||||||||||||||||||||
| .collect(); | ||||||||||||||||||||||
| .collect()); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| out.append(&mut self.val.encode_len()); | ||||||||||||||||||||||
|
Comment on lines
143
to
153
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -236,22 +239,15 @@ impl Tlv { | |||||||||||||||||||||
| fn read_tag(iter: &mut dyn ExactSizeIterator<Item = &u8>) -> Result<Tag> { | ||||||||||||||||||||||
| let mut tag: usize; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Per EMV 4.3 Book 3 Annex B1 (Coding of the Tag Field of BER-TLV Data Objects): | ||||||||||||||||||||||
| // > Before, between, or after TLV-coded data objects, '00' bytes without any meaning | ||||||||||||||||||||||
| // > may occur (for example, due to erased or modified TLV-coded data objects). | ||||||||||||||||||||||
| let first: u8 = iter | ||||||||||||||||||||||
| .skip_while(|&&next| next == 0) | ||||||||||||||||||||||
| .next() | ||||||||||||||||||||||
| .cloned() | ||||||||||||||||||||||
| .ok_or_else(|| TlvError::TruncatedTlv)?; | ||||||||||||||||||||||
| let first: u8 = iter.next().cloned().ok_or_else(|| TlvError::TruncatedTlv)?; | ||||||||||||||||||||||
|
||||||||||||||||||||||
| let first: u8 = iter.next().cloned().ok_or_else(|| TlvError::TruncatedTlv)?; | |
| // Skip leading 0x00 bytes (padding) before reading the actual tag. | |
| let first: u8 = loop { | |
| let byte = iter.next().cloned().ok_or_else(|| TlvError::TruncatedTlv)?; | |
| if byte == 0x00 { | |
| continue; | |
| } else { | |
| break byte; | |
| } | |
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming
InvalidTagNumberfrom a unit variant toInvalidTagNumber { is_zero: bool }is a public API breaking change for downstream code that pattern-matches onTlvError. Sinceis_zerois only used internally to detect/record leading padding bytes (and isn’t reflected in the Display message), consider handling that case without encoding internal details into the public error type (e.g., by peeking/consuming0x00bytes in the parser loop, or by using a private/internal error and mapping toInvalidTagNumber).