From 5b7e24d744340345c11578911e3f1fa4ab0fb9cc Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 19 Jul 2005 08:25:39 +0000 Subject: * io.c (rb_io_inspect): replace sprintf() with "%s" format all over the place by snprintf() to avoid integer overflow. * sample/svr.rb: service can be stopped by ill-behaved client; use tsvr.rb instead. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8799 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 22 ++++++++++++++++------ dln.c | 5 +++-- error.c | 5 +++-- eval.c | 19 ++++++++++++------- hash.c | 7 ++++--- io.c | 2 +- object.c | 17 +++++++++++------ sample/svr.rb | 8 +++++--- struct.c | 5 +++-- variable.c | 6 ++++-- 10 files changed, 62 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00ec8f42d4..3640a30cbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Jul 19 16:39:46 2005 Yukihiro Matsumoto + + * io.c (rb_io_inspect): replace sprintf() with "%s" format all + over the place by snprintf() to avoid integer overflow. + Tue Jul 19 14:08:22 2005 Hirokazu Yamamoto * ext/tcltklib/tcltklib.c: rbtk_eventloop_depth is used as int. @@ -105,12 +110,6 @@ Mon Jul 11 08:31:29 2005 Nobuyoshi Nakada * regex.c (read_special): fix parsing backslashes following \c in regexp. fixed: [ruby-dev:26500] -Sun Jul 10 22:18:17 CEST 2005 Michael Neumann - - * lib/xmlrpc/server.rb (XMLRPC::Server): Switch from GServer over to - WEBrick. This makes file lib/xmlrpc/httpserver.rb obsolete (at least it is - no further used by the XML-RPC library). - Mon Jul 11 02:53:00 2005 GOTOU Yuuzou * lib/webrick/cgi.rb (WEBrick::CGI::Socket#request_line): @@ -123,6 +122,12 @@ Sun Jul 10 23:58:04 2005 Tanaka Akira avoid unlink a directory by root. cf. [ruby-dev:26237] +Sun Jul 10 22:18:17 CEST 2005 Michael Neumann + + * lib/xmlrpc/server.rb (XMLRPC::Server): Switch from GServer over to + WEBrick. This makes file lib/xmlrpc/httpserver.rb obsolete (at least it is + no further used by the XML-RPC library). + Sun Jul 10 12:47:01 2005 Nobuyoshi Nakada * lib/debug.rb (debug_command): added a deficient format specifier. @@ -207,6 +212,11 @@ Tue Jul 5 14:51:35 2005 Hidetoshi NAGAI * ext/tk/lib/tk/namespace.rb: arguemnts for TclTkIp#_merge_tklist should be UTF-8 strings. +Mon Jul 4 14:35:52 2005 Yukihiro Matsumoto + + * sample/svr.rb: service can be stopped by ill-behaved client; use + tsvr.rb instead. + Mon Jul 4 13:25:21 2005 Yukihiro Matsumoto * missing/erf.c: original erf.c by prof. Okumura is confirmed to diff --git a/dln.c b/dln.c index fbfd6c2db2..0993a84161 100644 --- a/dln.c +++ b/dln.c @@ -962,8 +962,9 @@ load_lib(lib) dln_errno = DLN_EBADLIB; if (lib[0] == '-' && lib[1] == 'l') { - char *p = alloca(strlen(lib) + 4); - sprintf(p, "lib%s.a", lib+2); + long len = strlen(lib) + 4; + char *p = alloca(len); + snprintf(p, len, "lib%s.a", lib+2); lib = p; } diff --git a/error.c b/error.c index f741620ffe..0b63aa0512 100644 --- a/error.c +++ b/error.c @@ -907,9 +907,10 @@ syserr_initialize(argc, argv, self) else err = "unknown error"; if (!NIL_P(mesg)) { VALUE str = mesg; + size_t len = strlen(err)+RSTRING(str)->len+3; StringValue(str); - mesg = rb_str_new(0, strlen(err)+RSTRING(str)->len+3); - sprintf(RSTRING(mesg)->ptr, "%s - %.*s", err, + mesg = rb_str_new(0, len); + snprintf(RSTRING(mesg)->ptr, len, "%s - %.*s", err, (int)RSTRING(str)->len, RSTRING(str)->ptr); rb_str_resize(mesg, strlen(RSTRING(mesg)->ptr)); } diff --git a/eval.c b/eval.c index 5bc8229de2..cfd90f8e95 100644 --- a/eval.c +++ b/eval.c @@ -650,6 +650,7 @@ rb_attr(klass, id, read, write, ex) char *buf; ID attriv; int noex; + size_t len; if (!ex) noex = NOEX_PUBLIC; else { @@ -674,8 +675,9 @@ rb_attr(klass, id, read, write, ex) if (!name) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } - buf = ALLOCA_N(char,strlen(name)+2); - sprintf(buf, "@%s", name); + len = strlen(name)+2; + buf = ALLOCA_N(char,len); + snprintf(buf, len, "@%s", name); attriv = rb_intern(buf); if (read) { rb_add_method(klass, id, NEW_IVAR(attriv), noex); @@ -8508,12 +8510,14 @@ proc_to_s(self) if ((node = data->frame.node) || (node = data->body)) { len += strlen(node->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3; str = rb_str_new(0, len); - sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body, - node->nd_file, nd_line(node)); + snprintf(RSTRING(str)->ptr, len, + "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body, + node->nd_file, nd_line(node)); } else { str = rb_str_new(0, len); - sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx>", cname, w, (VALUE)data->body); + snprintf(RSTRING(str)->ptr, len, + "#<%s:0x%.*lx>", cname, w, (VALUE)data->body); } RSTRING(str)->len = strlen(RSTRING(str)->ptr); if (OBJ_TAINTED(self)) OBJ_TAINT(str); @@ -12262,9 +12266,10 @@ rb_thread_inspect(thread) rb_thread_t th = rb_thread_check(thread); const char *status = thread_status_name(th->status); VALUE str; + size_t len = strlen(cname)+7+16+9+1; - str = rb_str_new(0, strlen(cname)+7+16+9+1); /* 7:tags 16:addr 9:status 1:nul */ - sprintf(RSTRING(str)->ptr, "#<%s:0x%lx %s>", cname, thread, status); + str = rb_str_new(0, len); /* 7:tags 16:addr 9:status 1:nul */ + snprintf(RSTRING(str)->ptr, len, "#<%s:0x%lx %s>", cname, thread, status); RSTRING(str)->len = strlen(RSTRING(str)->ptr); OBJ_INFECT(str, thread); diff --git a/hash.c b/hash.c index 632f0dcaa9..09d866b133 100644 --- a/hash.c +++ b/hash.c @@ -1820,7 +1820,7 @@ ruby_setenv(name, value) else unsetenv(name); #else /* WIN32 */ - + size_t len; int i=envix(name); /* where does it go? */ if (environ == origenviron) { /* need we copy environment? */ @@ -1853,9 +1853,10 @@ ruby_setenv(name, value) REALLOC_N(environ, char*, i+2); /* just expand it a bit */ environ[i+1] = 0; /* make sure it's null terminated */ } - environ[i] = ALLOC_N(char, strlen(name) + strlen(value) + 2); + len = strlen(name) + strlen(value) + 2; + environ[i] = ALLOC_N(char, len); #ifndef MSDOS - sprintf(environ[i],"%s=%s",name,value); /* all that work just for this */ + snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */ #else /* MS-DOS requires environment variable names to be in uppercase */ /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but diff --git a/io.c b/io.c index c94109e112..746add0025 100644 --- a/io.c +++ b/io.c @@ -952,7 +952,7 @@ rb_io_inspect(obj) len += 9; } buf = ALLOCA_N(char, len); - sprintf(buf, "#<%s:%s%s>", cname, fptr->path, st); + snprintf(buf, len, "#<%s:%s%s>", cname, fptr->path, st); return rb_str_new2(buf); } diff --git a/object.c b/object.c index b250b52888..27af5b33e3 100644 --- a/object.c +++ b/object.c @@ -354,10 +354,12 @@ rb_any_to_s(obj) VALUE obj; { char *cname = rb_obj_classname(obj); + size_t len; VALUE str; - str = rb_str_new(0, strlen(cname)+6+16+1); /* 6:tags 16:addr 1:nul */ - sprintf(RSTRING(str)->ptr, "#<%s:0x%lx>", cname, obj); + len = strlen(cname)+6+16+1; + str = rb_str_new(0, len); /* 6:tags 16:addr 1:nul */ + snprintf(RSTRING(str)->ptr, len, "#<%s:0x%lx>", cname, obj); RSTRING(str)->len = strlen(RSTRING(str)->ptr); if (OBJ_TAINTED(obj)) OBJ_TAINT(str); @@ -433,17 +435,20 @@ rb_obj_inspect(obj) && ROBJECT(obj)->iv_tbl && ROBJECT(obj)->iv_tbl->num_entries > 0) { VALUE str; + size_t len; char *c; c = rb_obj_classname(obj); if (rb_inspecting_p(obj)) { - str = rb_str_new(0, strlen(c)+10+16+1); /* 10:tags 16:addr 1:nul */ - sprintf(RSTRING(str)->ptr, "#<%s:0x%lx ...>", c, obj); + len = strlen(c)+10+16+1; + str = rb_str_new(0, len); /* 10:tags 16:addr 1:nul */ + snprintf(RSTRING(str)->ptr, len, "#<%s:0x%lx ...>", c, obj); RSTRING(str)->len = strlen(RSTRING(str)->ptr); return str; } - str = rb_str_new(0, strlen(c)+6+16+1); /* 6:tags 16:addr 1:nul */ - sprintf(RSTRING(str)->ptr, "-<%s:0x%lx", c, obj); + len = strlen(c)+6+16+1; + str = rb_str_new(0, len); /* 6:tags 16:addr 1:nul */ + snprintf(RSTRING(str)->ptr, len, "-<%s:0x%lx", c, obj); RSTRING(str)->len = strlen(RSTRING(str)->ptr); return rb_protect_inspect(inspect_obj, obj, str); } diff --git a/sample/svr.rb b/sample/svr.rb index 6169861abc..11cfc5fbfe 100644 --- a/sample/svr.rb +++ b/sample/svr.rb @@ -1,6 +1,9 @@ # socket example - server side # usage: ruby svr.rb +# this server might be blocked by an ill-behaved client. +# see tsvr.rb which is safe from client blocking. + require "socket" gs = TCPserver.open(0) @@ -22,10 +25,9 @@ loop do print(s, " is gone\n") s.close socks.delete(s) - else - if str = s.gets + # single thread gets may block whole service + elsif str = s.gets s.write(str) - end end end end diff --git a/struct.c b/struct.c index 59de2ea618..ed3f9f28ee 100644 --- a/struct.c +++ b/struct.c @@ -518,9 +518,10 @@ rb_struct_inspect(s) { if (rb_inspecting_p(s)) { char *cname = rb_class2name(rb_obj_class(s)); - VALUE str = rb_str_new(0, strlen(cname) + 15); + size_t len = strlen(cname) + 15; + VALUE str = rb_str_new(0, len); - sprintf(RSTRING(str)->ptr, "#", cname); + snprintf(RSTRING(str)->ptr, len, "#", cname); RSTRING(str)->len = strlen(RSTRING(str)->ptr); return str; } diff --git a/variable.c b/variable.c index 04d826bf2d..7e56e8df89 100644 --- a/variable.c +++ b/variable.c @@ -196,6 +196,7 @@ rb_class_path(klass) } else { char *s = "Class"; + size_t len; if (TYPE(klass) == T_MODULE) { if (rb_obj_class(klass) == rb_cModule) { @@ -205,8 +206,9 @@ rb_class_path(klass) s = rb_class2name(RBASIC(klass)->klass); } } - path = rb_str_new(0, 2 + strlen(s) + 3 + 2 * SIZEOF_LONG + 1); - sprintf(RSTRING(path)->ptr, "#<%s:0x%lx>", s, klass); + len = 2 + strlen(s) + 3 + 2 * SIZEOF_LONG + 1; + path = rb_str_new(0, len); + snprintf(RSTRING(path)->ptr, len, "#<%s:0x%lx>", s, klass); RSTRING(path)->len = strlen(RSTRING(path)->ptr); rb_ivar_set(klass, tmp_classpath, path); -- cgit v1.2.3