-
Notifications
You must be signed in to change notification settings - Fork 201
Description
Issue
I have a situation where there is a list of data types.
Before the list-entries (entries
) are given, a maximum number of entries is given (max_num_entries
) at the head of the list.
Additionally, any list entry may meet a condition which denotes it as the terminal entry - ending the list preemptively (before the max number of entries is reached).
Here is a minimal example of the phenomena
(Note that for this particular example there is a more elegant/proper solution; this is merely illustrating the problem).
seq:
- id: first_list
type: list_type
- id: second_list
type: list_type
types:
list_type:
seq:
- id: max_num_entries
type: u1
- id: entries
type: u1 # in reality the entry is more complex than a 'u1'
repeat: until
# in reality the terminator is more complex than a value of '0xFF'
repeat-until: _ == 0xFF or _index >= max_num_entries
Here, a repeat-until
expression checks to see if either the
terminal condition _ == 0xFF
is met or if the _index
exceeds the max number of entries.
The behavior of the javascript
compiler (and kaitai IDE) is as expected.
Here is the noteworthy piece of code generated:
ListType.prototype._read = function() {
this.maxNumEntries = this._io.readU1();
this.entries = []
var i = 0;
do {
var _ = this._io.readU1();
this.entries.push(_);
i++;
} while (!( ((_ == 255) || (i >= this.maxNumEntries)) ));
}
Compare this to the python
output of the compiler
def _read(self):
self.max_num_entries = self._io.read_u1()
self.entries = []
i = 0
while True:
_ = self._io.read_u1()
self.entries.append(_)
if ((_ == 255) or (i >= self.max_num_entries)) :
break
i += 1
Hopefully the problem here is apparent - the value of i
is incremented before the loop check in the javascript code,
while the value of i
is incremented after the loop check in the python code.
In order to achieve the same behavior for python, the ksy
must be modified to
repeat-until: _ == 0xFF or _index >= (max_num_entries - 1)
Proposed Fix
For each target language, ensure that the 'loop check' generated by a repeat-until
expression is
the last thing to execute in its requisite repeat block.
I've searched the issues and haven't found anything similar,
however I may not have been using the appropriate keywords.