ruby-changes:44174
From: rhe <ko1@a...>
Date: Mon, 26 Sep 2016 11:09:55 +0900 (JST)
Subject: [ruby-changes:44174] rhe:r56247 (trunk): string.c: fix integer overflow in enc_strlen() and rb_enc_strlen_cr()
rhe 2016-09-26 11:09:50 +0900 (Mon, 26 Sep 2016) New Revision: 56247 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56247 Log: string.c: fix integer overflow in enc_strlen() and rb_enc_strlen_cr() * string.c (enc_strlen, rb_enc_strlen_cr): Avoid signed integer overflow. The result type of a pointer subtraction may have the same size as long. This fixes String#size returning an negative value on i686-linux environment: str = "\x00" * ((1<<31)-2)) str.slice!(-3, 3) str.force_encoding("UTF-32BE") str << 1234 p str.size Modified files: trunk/ChangeLog trunk/string.c Index: string.c =================================================================== --- string.c (revision 56246) +++ string.c (revision 56247) @@ -1527,7 +1527,8 @@ enc_strlen(const char *p, const char *e, https://github.com/ruby/ruby/blob/trunk/string.c#L1527 const char *q; if (rb_enc_mbmaxlen(enc) == rb_enc_mbminlen(enc)) { - return (e - p + rb_enc_mbminlen(enc) - 1) / rb_enc_mbminlen(enc); + long diff = (long)(e - p); + return diff / rb_enc_mbminlen(enc) + !!(diff % rb_enc_mbminlen(enc)); } #ifdef NONASCII_MASK else if (cr == ENC_CODERANGE_VALID && enc == rb_utf8_encoding()) { @@ -1609,7 +1610,8 @@ rb_enc_strlen_cr(const char *p, const ch https://github.com/ruby/ruby/blob/trunk/string.c#L1610 *cr = 0; if (rb_enc_mbmaxlen(enc) == rb_enc_mbminlen(enc)) { - return (e - p + rb_enc_mbminlen(enc) - 1) / rb_enc_mbminlen(enc); + long diff = (long)(e - p); + return diff / rb_enc_mbminlen(enc) + !!(diff % rb_enc_mbminlen(enc)); } else if (rb_enc_asciicompat(enc)) { c = 0; Index: ChangeLog =================================================================== --- ChangeLog (revision 56246) +++ ChangeLog (revision 56247) @@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon Sep 26 11:06:47 2016 Kazuki Yamaguchi <k@r...> + + * string.c (enc_strlen, rb_enc_strlen_cr): Avoid signed integer + overflow. The result type of a pointer subtraction may have the same + size as long. This fixes String#size returning an negative value on + i686-linux environment: + + str = "\x00" * ((1<<31)-2)) + str.slice!(-3, 3) + str.force_encoding("UTF-32BE") + str << 1234 + p str.size + Sun Sep 25 22:48:06 2016 namusyaka <namusyaka@g...> * lib/erb.rb (ERB::Compiler::TrimScanner#stag): The :stag accessor -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/