summaryrefslogtreecommitdiff
path: root/ext/zlib/zlib.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-10-27 02:46:54 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-10-27 02:46:54 +0000
commitece87af00c6e31181b7092980a351929c5421a43 (patch)
tree69f926f26570f7cbe08fe38dca0c011e8051e945 /ext/zlib/zlib.c
parent5615f7636e54d7010a1974bfa79ef2e31a44ffbd (diff)
* string.c (RESIZE_CAPA): check string attribute before modifying
capacity member of string structure. [ruby-dev:24594] * ext/zlib/zlib.c (gzreader_gets): use memchr() to to gain performance. [ruby-talk:117701] * sprintf.c (rb_f_sprintf): raise ArgumentError for extra arguments, unless (digit)$ style used. * ext/zlib/zlib.c (gzreader_gets): use memchr() to to gain performance. [ruby-talk:117701] * sprintf.c (rb_f_sprintf): raise ArgumentError for extra arguments, unless (digit)$ style used. * eval.c (frame_free): Guy Decoux solved the leak problem. Thanks. [ruby-core:03549] * ext/zlib/zlib.c (zstream_append_input): clear klass for z->input to avoid potential vulnerability. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/zlib/zlib.c')
-rw-r--r--ext/zlib/zlib.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index f44a4ee209..44a9f3ea7b 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -527,7 +527,6 @@ zstream_detach_buffer(z)
dst = z->buf;
rb_str_resize(dst, z->buf_filled);
RBASIC(dst)->klass = rb_cString;
- RBASIC(dst)->klass = rb_cString;
}
z->buf = Qnil;
@@ -591,6 +590,7 @@ zstream_append_input(z, src, len)
if (NIL_P(z->input)) {
z->input = rb_str_buf_new(len);
rb_str_buf_cat(z->input, src, len);
+ RBASIC(z->input)->klass = 0;
}
else {
rb_str_buf_cat(z->input, src, len);
@@ -698,9 +698,9 @@ zstream_run(z, src, len, flush)
uInt n;
int err;
- if (NIL_P(z->input)) {
- z->stream.next_in = src;
- z->stream.avail_in = len;
+ if (NIL_P(z->input) && len == 0) {
+ z->stream.next_in = "";
+ z->stream.avail_in = 0;
}
else {
zstream_append_input(z, src, len);
@@ -2056,7 +2056,7 @@ static long
gzfile_read_more(gz)
struct gzfile *gz;
{
- VALUE str;
+ volatile VALUE str;
while (!ZSTREAM_IS_FINISHED(&gz->z)) {
str = gzfile_read_raw(gz);
@@ -3032,6 +3032,16 @@ gzreader_skip_linebreaks(gz)
gzfile_calc_crc(gz, str);
}
+static void
+rscheck(rsptr, rslen, rs)
+ char *rsptr;
+ long rslen;
+ VALUE rs;
+{
+ if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)
+ rb_raise(rb_eRuntimeError, "rs modified");
+}
+
static VALUE
gzreader_gets(argc, argv, obj)
int argc;
@@ -3039,8 +3049,9 @@ gzreader_gets(argc, argv, obj)
VALUE obj;
{
struct gzfile *gz = get_gzfile(obj);
- VALUE rs, dst;
- char *rsptr, *p;
+ volatile VALUE rs;
+ VALUE dst;
+ char *rsptr, *p, *res;
long rslen, n;
int rspara;
@@ -3082,16 +3093,24 @@ gzreader_gets(argc, argv, obj)
gzfile_read_more(gz);
}
- n = rslen;
p = RSTRING(gz->z.buf)->ptr;
+ n = rslen;
for (;;) {
if (n > gz->z.buf_filled) {
if (ZSTREAM_IS_FINISHED(&gz->z)) break;
gzfile_read_more(gz);
p = RSTRING(gz->z.buf)->ptr + n - rslen;
}
- if (memcmp(p, rsptr, rslen) == 0) break;
- p++, n++;
+ if (!rspara) rscheck(rsptr, rslen, rs);
+ res = memchr(p, rsptr[0], (gz->z.buf_filled - n + 1));
+ if (!res) {
+ n = gz->z.buf_filled + 1;
+ } else {
+ n += (long)(res - p);
+ p = res;
+ if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
+ p++, n++;
+ }
}
gz->lineno++;