mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
tkutil.c: fix memory leak and segfault
* ext/tk/tkutil/tkutil.c (cbsubst_append_inf_key): extract a function append a key in subst info to a string. make result strings first and get rid of potential memory leak. * ext/tk/tkutil/tkutil.c (cbsubst_get_subst_arg): allocate the result buffer as a string to fix: * memory leak when the argument key is not found: loop {Tk::Event.subst_arg(:a) rescue nil} * buffer overflow segfault when many arguments: class T < TkUtil::CallbackSubst _setup_subst_table([[?a, ?A, :_a]], []) subst_arg(*[:_a]*1000).size end git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50704 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1611735b29
commit
30e6825e1b
1 changed files with 50 additions and 79 deletions
|
@ -1323,6 +1323,39 @@ cbsubst_def_attr_aliases(self, tbl)
|
||||||
return rb_funcall(inf->aliases, rb_intern("update"), 1, tbl);
|
return rb_funcall(inf->aliases, rb_intern("update"), 1, tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
cbsubst_append_inf_key(str, inf, idx)
|
||||||
|
VALUE str;
|
||||||
|
const struct cbsubst_info *inf;
|
||||||
|
int idx;
|
||||||
|
{
|
||||||
|
const long len = inf->keylen[idx];
|
||||||
|
const long olen = RSTRING_LEN(str);
|
||||||
|
char *buf, *ptr;
|
||||||
|
|
||||||
|
rb_str_modify_expand(str, (len ? len : 1) + 2);
|
||||||
|
buf = RSTRING_PTR(str);
|
||||||
|
ptr = buf + olen;
|
||||||
|
|
||||||
|
*(ptr++) = '%';
|
||||||
|
|
||||||
|
if (len != 0) {
|
||||||
|
/* longname */
|
||||||
|
strncpy(ptr, inf->key[idx], len);
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* single char */
|
||||||
|
*(ptr++) = (unsigned char)idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(ptr++) = ' ';
|
||||||
|
|
||||||
|
rb_str_set_len(str, ptr - buf);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
cbsubst_sym_to_subst(self, sym)
|
cbsubst_sym_to_subst(self, sym)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
|
@ -1330,9 +1363,7 @@ cbsubst_sym_to_subst(self, sym)
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
char *buf, *ptr;
|
|
||||||
int idx;
|
int idx;
|
||||||
long len;
|
|
||||||
ID id;
|
ID id;
|
||||||
volatile VALUE ret;
|
volatile VALUE ret;
|
||||||
|
|
||||||
|
@ -1353,27 +1384,7 @@ cbsubst_sym_to_subst(self, sym)
|
||||||
}
|
}
|
||||||
if (idx >= CBSUBST_TBL_MAX) return sym;
|
if (idx >= CBSUBST_TBL_MAX) return sym;
|
||||||
|
|
||||||
ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
|
return cbsubst_append_inf_key(rb_str_new(0, 0), inf, idx);
|
||||||
|
|
||||||
*(ptr++) = '%';
|
|
||||||
|
|
||||||
if ((len = inf->keylen[idx]) != 0) {
|
|
||||||
/* longname */
|
|
||||||
strncpy(ptr, inf->key[idx], len);
|
|
||||||
ptr += len;
|
|
||||||
} else {
|
|
||||||
/* single char */
|
|
||||||
*(ptr++) = (unsigned char)idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(ptr++) = ' ';
|
|
||||||
*(ptr++) = '\0';
|
|
||||||
|
|
||||||
ret = rb_str_new2(buf);
|
|
||||||
|
|
||||||
xfree(buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1384,16 +1395,13 @@ cbsubst_get_subst_arg(argc, argv, self)
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
char *buf, *ptr;
|
|
||||||
int i, idx;
|
int i, idx;
|
||||||
long len;
|
|
||||||
ID id;
|
ID id;
|
||||||
volatile VALUE arg_sym, ret;
|
VALUE arg_sym, ret, result;
|
||||||
|
|
||||||
inf = cbsubst_get_ptr(self);
|
inf = cbsubst_get_ptr(self);
|
||||||
|
|
||||||
ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
|
result = rb_str_new(0, 0);
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
switch(TYPE(argv[i])) {
|
switch(TYPE(argv[i])) {
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
|
@ -1425,27 +1433,10 @@ cbsubst_get_subst_arg(argc, argv, self)
|
||||||
rb_raise(rb_eArgError, "cannot find attribute :%"PRIsVALUE, str);
|
rb_raise(rb_eArgError, "cannot find attribute :%"PRIsVALUE, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(ptr++) = '%';
|
result = cbsubst_append_inf_key(result, inf, idx);
|
||||||
|
|
||||||
if ((len = inf->keylen[idx]) != 0) {
|
|
||||||
/* longname */
|
|
||||||
strncpy(ptr, inf->key[idx], len);
|
|
||||||
ptr += len;
|
|
||||||
} else {
|
|
||||||
/* single char */
|
|
||||||
*(ptr++) = (unsigned char)idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(ptr++) = ' ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ptr = '\0';
|
return result;
|
||||||
|
|
||||||
ret = rb_str_new2(buf);
|
|
||||||
|
|
||||||
xfree(buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1454,8 +1445,8 @@ cbsubst_get_subst_key(self, str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
volatile VALUE list;
|
VALUE list;
|
||||||
volatile VALUE ret;
|
VALUE ret;
|
||||||
long i, len, keylen;
|
long i, len, keylen;
|
||||||
int idx;
|
int idx;
|
||||||
char *buf, *ptr;
|
char *buf, *ptr;
|
||||||
|
@ -1466,7 +1457,8 @@ cbsubst_get_subst_key(self, str)
|
||||||
|
|
||||||
inf = cbsubst_get_ptr(self);
|
inf = cbsubst_get_ptr(self);
|
||||||
|
|
||||||
ptr = buf = ALLOC_N(char, len + 1);
|
ret = rb_str_new(0, len);
|
||||||
|
ptr = buf = RSTRING_PTR(ret);
|
||||||
|
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
VALUE keyval = RARRAY_CONST_PTR(list)[i];
|
VALUE keyval = RARRAY_CONST_PTR(list)[i];
|
||||||
|
@ -1494,10 +1486,8 @@ cbsubst_get_subst_key(self, str)
|
||||||
*(ptr++) = ' ';
|
*(ptr++) = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ptr = '\0';
|
|
||||||
|
|
||||||
ret = rb_str_new2(buf);
|
rb_str_set_len(ret, ptr - buf);
|
||||||
xfree(buf);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1506,45 +1496,26 @@ cbsubst_get_all_subst_keys(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
char *buf, *ptr;
|
|
||||||
char *keys_buf, *keys_ptr;
|
char *keys_buf, *keys_ptr;
|
||||||
int idx;
|
int idx;
|
||||||
long len;
|
VALUE str, keys_str;
|
||||||
volatile VALUE ret;
|
|
||||||
|
|
||||||
inf = cbsubst_get_ptr(self);
|
inf = cbsubst_get_ptr(self);
|
||||||
|
|
||||||
ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
|
str = rb_str_new(0, 0);
|
||||||
keys_ptr = keys_buf = ALLOC_N(char, CBSUBST_TBL_MAX + 1);
|
keys_str = rb_str_new(0, CBSUBST_TBL_MAX);
|
||||||
|
keys_ptr = keys_buf = RSTRING_PTR(keys_str);
|
||||||
|
|
||||||
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
if (inf->ivar[idx] == (ID) 0) continue;
|
if (inf->ivar[idx] == (ID) 0) continue;
|
||||||
|
|
||||||
*(keys_ptr++) = (unsigned char)idx;
|
*(keys_ptr++) = (unsigned char)idx;
|
||||||
|
|
||||||
*(ptr++) = '%';
|
str = cbsubst_append_inf_key(str, inf, idx);
|
||||||
|
|
||||||
if ((len = inf->keylen[idx]) != 0) {
|
|
||||||
/* longname */
|
|
||||||
strncpy(ptr, inf->key[idx], len);
|
|
||||||
ptr += len;
|
|
||||||
} else {
|
|
||||||
/* single char */
|
|
||||||
*(ptr++) = (unsigned char)idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(ptr++) = ' ';
|
|
||||||
}
|
}
|
||||||
|
rb_str_set_len(keys_str, keys_ptr - keys_buf);
|
||||||
|
|
||||||
*ptr = '\0';
|
return rb_ary_new3(2, keys_str, str);
|
||||||
*keys_ptr = '\0';
|
|
||||||
|
|
||||||
ret = rb_ary_new3(2, rb_str_new2(keys_buf), rb_str_new2(buf));
|
|
||||||
|
|
||||||
xfree(buf);
|
|
||||||
xfree(keys_buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
Loading…
Add table
Reference in a new issue