3 ms·
I think it's easy to hand write a parser that can get into a weird state. Some formats are also easier to write a parser for safely vs others. For example, if
by insanitybit 4y ago
I think it's easy to hand write a parser that can get into a weird state. Some formats are also easier to write a parser for safely vs others.
For example, if you have a Tag Length Value data format that says "5ABCDE" maybe that means "the next 5 bytes are a string, then there's something else afterwards or it's the end", you don't want to allocate a buffer of 5 values and just keep writing into it without checking that you're reading valid values.
Doing this sort of thing efficiently may also mean that you're tempted to remove something like a bounds check. After all, if you already know that the value is 5 bytes, why check on every access? People really want parsers to be fast. Ideally in the above example I wouldn't even need to copy those bytes out, I could just reference those values, which now leads to potential lifetime issues.
Further, in C, buffers don't have lengths attached to them. In every other language you typically don't work with null terminated strings. So now you have to manage sizes of things throughout your parser.
One way to view this is that the programmer's mental model of the parsing machine can easily drift from the implementation of the parsing machine, leading to vulnerabilities.
Basically it ends up being very easy to accidentally end up with out of bounds reads/writes + there's pressure to be fast + formats can be very complex.
That's my view on it at least.
- tester756 4y ago>Doing this sort of thing efficiently may also mean that you're tempted to remove something like a bounds check. After all, if you already know that the value is 5 bytes, why check on every access? People really want parsers to be fast. In what kind of software bounds check have this significant perf. penalty? The only people I've heard talking about such a stuff were firmware devs. >Further, in C, buffers don't have lengths attached to them. In every other language you typically don't work with null terminated strings. So now you have to manage sizes of things throughout your parser. Cannot C have some wrapper over those poor strings that leads to better safety? dev's experience, etc, etc?
- insanitybit 4y ago> In what kind of software bounds check have this significant perf. penalty? All kinds. But a lot of it is just that parsers are extremely easy to benchmark and benchmarks promote optimization. > Cannot C have some wrapper over those poor strings Sure, but there's nothing native.
- tester756 4y ago>Sure, but there's nothing native. But why? strings are used by all programmers everyday I struggle to understand why you wouldn't want to make them state of the art, or decent at least.
- insanitybit 4y agoC is an extremely conservative language. You don't even get booleans unless you're in C99 and import it.
- int_19h 4y agoYou do get them without #include <stdbool.h>, you'll just have to contend with ugly spellings like _Bool and _True.
- anjbe 4y agobool, true, and false as native keywords are on track to show up in C23. https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2393.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2393.pdf
- thephyber 4y ago> > Sure, but there's nothing native. > But why? strings are used by all programmers everyday Different kinds of strings can have extremely different performance profiles. A statically allocated string of ASCII (single byte) characters. A dynamically allocated string of unicode (multibyte) characters where the length of allocation is not known ahead of time is very different. C requires the developer to know the differences and knows how to deal with them treat them.
- pjmlp 4y agoBecause WG14 doesn't care about security, for them C is basically a portable macro assembler with added conveniences.