-
Notifications
You must be signed in to change notification settings - Fork 201
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
Checksumming, other constraints and asserts validation and exceptions #81
Comments
Calculating checksums is a fairly complex issue, and, to be fair, it is not needed for the primary task that KS performs, i.e. parsing. Calculating checksums, of course, would be most useful for #27. As far as I see it, there are several subproblems with this one:
@KOLANICH note that |
how about throw: #```throw``` block is proposed to be an ```instances``` block bound to the generated exception object but with one-time (at the time of creation) access to all the local variables.
if: checksum_checksum_type(....) != expected_value
result: # the member name in exception object
type: u1 # the type of member
enum: error # the values are from the ```error``` enum.
value: 'error::it_happened_again' # the value set to a member. Essentially it is the same that a ```value``` in instances, but we should be able to use visible variables here.
........
enums:
error:
1: it_happenned_again
2: that_happenned_again |
My issue is that I have a function for checksumming, offered by the protocol developers. It expects the pointer to the parsed structure and its size in bytes. Then it does some operations on it and returns the checksum. Something like:
All I need to do is to give the CalcCRC the pointer to the structure, but since kaitai structure contains vectors and strings, the function does not receive the initial package that way. What I do now is I read the stream into some dummy array and give the CalcCRC pointer to it. If the sum is okay, I seek PktSize bytes back and read the data again, but into kaitai structure that time. I thought maybe there could be a more elegant solution. |
@MariaChakchurina I believe, you can do something like that: my_struct_t my_struct(&ks);
my_struct._io()->seek(0);
std::string buf = my_struct._io()->read_bytes_full();
uint8_t crc = CalcCRC(&buf[0], buf.size());
if (crc != my_struct.crc_field()) {
// throw some exception or something
} It's not a huge difference, but at least you don't have to derive CRC field from your structure manually. |
I have multiple datagrams in a stream so I can't move the pointer to its beginning, but want to return data_size bytes back, so I better do:
Just letting you know;) |
Can't you do one substream per datagram then? It should be much more convenient. |
Um, #33 seems to have nothing to do with this topic, and #44 is planned future, which will optimize things a little, but you can still use substreams right now. Generally, when you do: seq:
- id: packet
type: some_datagram_type you don't create a substream, i.e. stream for the However, if you'll do something like that: seq:
- id: packet
type: some_datagram_type
size: 100 => it will create a substream in |
Excuse me, by 33 I meant that one https://github.com/kaitai-io/kaitai_struct_compiler/issues/33. Thank you, now I got it. |
@KOLANICH Just for the record, I don't understand most of this proposal:
What is |
What is `type`?
The type of the field with the id "result" in exception object.
What is `enum`?
the "result" in the example is the error code from the "error" enum, so
That is `value`?
The value of the result. There is a syntax error here: I should have used ""error::it_happenned_again""". I have fixed and amended the example. Any expression can be allowed for instances. ```throw``` block is proposed to be an ```instances``` block bound to the generated exception object but with one-time (at the time of creation) access to all the local variables.
|
You cannot throw arbitrary objects in several supported languages, so with this approach we should create a distinct exception class (according to the result type) on-the-fly which would make the parameters obsolate (as the class would identify the exception by itself). What came into my mind regarding exceptions:
Of course even if we create specific exceptions (option 2 & 3) those should be inherited from a common exception class which is defined in the runtime. So every Kaitai exception could be caught at once if needed. |
which would make the parameters obsolate (as the class would identify the exception by itself).
Are you going to have a separate exception class for every u8 number and a separate exception class for every string possible and how are you going to achieve this? We would like to provide some context without ruining exception safety (on exception everything over the catch must be destroyed, the resources freed, not leaked). So we would need some context to be able to give the error messages like "invalid opcode: foo", "100 (offset) > 2 (length)".
Do do distinguishing between exceptions right we need runtime-parameterized types with instantiation syntax first. Another approach is to have only one exception type per type and throw only it from the type, but this approach is crippled.
|
Forgot to add xrefs here: kaitai-io/kaitai_struct_formats#625 kaitai-io/kaitai_struct_formats#624 |
http://download.intel.com/support/motherboards/desktop/sb/pnpbiosspecificationv10a.pdf
So we need a way to verify checksums.
the proposed way is
if: checksum_checksum_type(....) == expected_value
where
checksum_checksum_type
calculates checksum, in the case from quote it sums every byte in the structure modulo 256 and we checkif: checksum_sum() == 0
.The text was updated successfully, but these errors were encountered: