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

Non 0 marker is incorrectly implemented. #1

Closed
janderholm opened this issue Jul 25, 2022 · 3 comments · Fixed by #2
Closed

Non 0 marker is incorrectly implemented. #1

janderholm opened this issue Jul 25, 2022 · 3 comments · Fixed by #2

Comments

@janderholm
Copy link

The library is not able to remove occurrences of the selected marker when the marker is not NULL. If the length to the next encoded byte is equal to the marker, it ends up in the output. See the following test:

    #[test]
    fn length_to_next_marker_equals_marker_value() {
        let transfer: [u8; 130] = stuff(
            *b"----------------------------------------------------------------A----------------------------------------------------------------",
            b'A'
        );

        // Uncomment and include "ascii" in Cargo.toml to see look at data
        //let s = ascii::AsciiStr::from_ascii(&transfer).unwrap();
        //println!("{:?}", s.as_str());

        // Now the data won't contain 'i's anymore except for the terminator byte.
        assert!(transfer.into_iter().all(|byte| *byte != b'A'));
    }

If we print the encoded string we find there are A characters in it (and the assert fails):
"A----------------------------------------------------------------A----------------------------------------------------------------"

Since the distance to the next A is equal to A, they still end up in the output buffer.

I have skimmed through the COBS specification papers. The suggested way to handle this case is to first eliminate any zeros, and then XOR the output buffer with the value to be eliminated (i.e. A in this case)

Here follows an extract from page 4 of the Consistent Overhead Byte Stuffing paper:
http://conferences.sigcomm.org/sigcomm/1997/papers/p062.pdf

It is also simple to eliminate some value other than
zero from the data stream, should that be necessary.
For example, a radio interface that connects through
the serial port like a Hayes modem might use an
ASCII carriage return (byte value 0x0D) to mark the
end of each packet [Che95]. By taking the output of
COBS and XORing each byte with 0x0D before
sending it to the radio, the COBS output is easily
converted into a form suitable for transmission over
this radio device. The only value that gives the result
0x0D when XORed with 0x0D is zero, and since there
are no zeroes in the output from COBS, this procedure
cannot result in any occurrences of 0x0D in the
converted output. The receiver XORs each received
byte with 0x0D to reverse the transformation before
feeding it to the COBS decoder, so that the data is
decoded correctly. Of course, in real implementations,
the COBS encoding and the output conversion are
performed in a single loop for efficiency reasons
[Cla90]

@coastalwhite
Copy link
Owner

Thank you for bringing this to my attention. I will have a look at fixing this on Friday.

@coastalwhite
Copy link
Owner

Thank you, Johan. This should now be fixed in version 1.1.2.

@janderholm
Copy link
Author

Thank you!

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

Successfully merging a pull request may close this issue.

2 participants