From 7213568733f673da0d82f95e8a1bccf79ba3f0d3 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Mon, 19 Nov 2018 09:52:46 +0000 Subject: string.c: setbyte silently ignores upper bits The behaviour of String#setbyte has been depending on the width of int, which is not portable. Must check explicitly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65804 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- string.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'string.c') diff --git a/string.c b/string.c index 5a5cbb576c..e55c59136a 100644 --- a/string.c +++ b/string.c @@ -5413,7 +5413,8 @@ rb_str_setbyte(VALUE str, VALUE index, VALUE value) long pos = NUM2LONG(index); int byte = NUM2INT(value); long len = RSTRING_LEN(str); - char *head, *ptr, *left = 0; + char *head, *left = 0; + unsigned char *ptr; rb_encoding *enc; int cr = ENC_CODERANGE_UNKNOWN, width, nlen; @@ -5421,17 +5422,21 @@ rb_str_setbyte(VALUE str, VALUE index, VALUE value) rb_raise(rb_eIndexError, "index %ld out of string", pos); if (pos < 0) pos += len; + if (byte < 0) + rb_raise(rb_eRangeError, "integer %d too small to convert into `unsigned char'", byte); + if (UCHAR_MAX < byte) + rb_raise(rb_eRangeError, "integer %d too big to convert into `unsigned char'", byte); if (!str_independent(str)) str_make_independent(str); enc = STR_ENC_GET(str); head = RSTRING_PTR(str); - ptr = &head[pos]; + ptr = (unsigned char *)&head[pos]; if (!STR_EMBED_P(str)) { cr = ENC_CODERANGE(str); switch (cr) { case ENC_CODERANGE_7BIT: - left = ptr; + left = (char *)ptr; *ptr = byte; if (ISASCII(byte)) goto end; nlen = rb_enc_precise_mbclen(left, head+len, enc); -- cgit v1.2.3