In fact, it appears when excel_tricks is true and when a field starts with '0', do not contains any occurrence of '\n', '\r' or the separator, and have a length of the form (8 * n - 1). In this case, the function must_quote returns -1, and the buffer s allocated on csv.ml line 800 is too small by 1 to store all the characters. The last Byte.unsafe_set then corrupts the size tag of the string s (when String.length n mod 8 = 7) or looses the last char in the 0-padding of the string (when String.length n mod 8 < 7). This memory corruption implies funny bugs when the string s is used later.
Anyway, many thanks for this very useful and efficient code!
The given patch fixes a bug that implied memory corruptions in some cases. The bug is observable on the following code:
Csv.output_all (Csv.to_channel ~excel_tricks:true stdout) [ [ "01234567" ] ]
In fact, it appears when excel_tricks is true and when a field starts with '0', do not contains any occurrence of '\n', '\r' or the separator, and have a length of the form (8 * n - 1). In this case, the function must_quote returns -1, and the buffer s allocated on csv.ml line 800 is too small by 1 to store all the characters. The last Byte.unsafe_set then corrupts the size tag of the string s (when String.length n mod 8 = 7) or looses the last char in the 0-padding of the string (when String.length n mod 8 < 7). This memory corruption implies funny bugs when the string s is used later.
Anyway, many thanks for this very useful and efficient code!
Benoît.