[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Silent change to string.pack("cn",...) between 5.3.1 and 5.3.2
- From: Duane Leslie <parakleta@...>
- Date: Thu, 7 Apr 2016 13:34:16 +1000
I have discovered that the behaviour for the 'fixed size string with n bytes' has been changed in a way that is arguably more convenient but now breaks the promise about packing that 'string.pack checks whether the given value fits in the given size'. This change was silently applied between 5.3.1 and 5.3.2.
Previously you had to provide strings that were exactly the length specified by the format, and if they weren't the length specified this generated an error. Now instead the behaviour is that if the string is too short it is padded with LUA_PACKPADBYTE (not necessarily '\0') and if it is too long it is silently truncated.
I think this is a mistake. The user can call str.sub() if they want to restrict to a particular length so the silent truncation is not an advantage. The padding option is definitely convenient but I dislike padding with LUA_PACKPADBYTE rather than '\0' and when unpacking this string the pad bytes are actually included in the returned string which may be unexpected (i.e. #("c8"):unpack(("c8"):pack("abc")) ~= #"abc").
I think the silent truncation behaviour should be reversed, but I have no position on the padding issue. I would like to ask though that an optional length argument be made available to the 'z' option which would specify a maximum length and pad specifically with '\0' which are dropped when unpacked. 'z' could guarantee at least one trailing '\0' is available, although there are other ways to achieve this if it is required (consider ("z16"):pack("hello world") vs ("z15B"):pack("hello world", 0) or simpler ("z15x"):pack("hello world") although this assumes padding is '\0').