-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
When using Stream::readBytesUntil() and specifying a non-printable ASCII target byte (such as 0xFE) the function does not stop reading bytes when the target is encountered. However, when a printable ASCII byte value is specified as the target (such as 0x71 or 'q') the function does stop reading bytes as expected.
This seems to occur because in the function source the following comparison is made:
int c = timedRead();
if (c < 0 || c == terminator) break;
The variable "c" must be an int since timedRead() returns an int that is -1 if no data is available to read. The 2 byte signed int value for -1 (0xFFFF) can be differentiated from the single byte value 0xFF which could be a possible valid returned read byte from the stream. In its returned int form this value would be 0x00FF and would be interpreted as 255 rather than -1 in any logic test (such as c<0 as seen in the first part of the logic test in the code above). However, when performing an equality test (such as in the second part of the logic test above) between a two byte int value ("c") and a single byte char value (such as "terminator") the test only evaluates true if the values match and correspond to a printable ASCII character. The test fails if the values correspond to a non-printable ASCII character, even if they match. This may be related to a larger issue involving the primitive equality test when comparing variables of different types.
To extend the ability of Stream::readBytesUntil() to function for non-printable target bytes suggest the following change in the source:
if (c < 0 || (char)c == terminator) break;
By casting "c" to a char in the second part of the logic test the test will evaluate true if the byte values match regardless of whether they correspond to printable ASCII characters or not.