signal.c: packed signals

* signal.c (signals): pack signal names instead of references.

* signal.c (signm2signo): also reject too long signal name.
  [ruby-core:87767] [Bug #14893]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63841 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-07-03 13:34:56 +00:00
parent a982952e32
commit a0e141b34f

View File

@ -62,8 +62,11 @@ ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp,
} }
#endif #endif
#define FOREACH_SIGNAL(sig, offset) \
for (sig = siglist + (offset); sig < siglist + numberof(siglist); ++sig)
static const int LONGEST_SIGNAME = 7; /* MIGRATE and RETRACT */
static const struct signals { static const struct signals {
const char *signm; char signm[LONGEST_SIGNAME + 1];
int signo; int signo;
} siglist [] = { } siglist [] = {
{"EXIT", 0}, {"EXIT", 0},
@ -192,7 +195,6 @@ static const struct signals {
#ifdef SIGINFO #ifdef SIGINFO
{"INFO", SIGINFO}, {"INFO", SIGINFO},
#endif #endif
{NULL, 0}
}; };
static const char signame_prefix[3] = "SIG"; static const char signame_prefix[3] = "SIG";
@ -204,7 +206,7 @@ signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr)
const struct signals *sigs; const struct signals *sigs;
VALUE vsig = *sig_ptr; VALUE vsig = *sig_ptr;
const char *nm; const char *nm;
long len; long len, nmlen;
int prefix = 0; int prefix = 0;
if (RB_SYMBOL_P(vsig)) { if (RB_SYMBOL_P(vsig)) {
@ -258,9 +260,12 @@ signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr)
} }
if (prefix_ptr) *prefix_ptr = prefix; if (prefix_ptr) *prefix_ptr = prefix;
for (sigs = siglist + !exit; sigs->signm; sigs++) { nmlen = len - prefix;
if (memcmp(sigs->signm, nm + prefix, len - prefix) == 0 && nm += prefix;
sigs->signm[len - prefix] == '\0') { if (nmlen > LONGEST_SIGNAME) goto unsupported;
FOREACH_SIGNAL(sigs, !exit) {
if (memcmp(sigs->signm, nm, nmlen) == 0 &&
sigs->signm[nmlen] == '\0') {
return negative ? -sigs->signo : sigs->signo; return negative ? -sigs->signo : sigs->signo;
} }
} }
@ -272,9 +277,10 @@ signo2signm(int no)
{ {
const struct signals *sigs; const struct signals *sigs;
for (sigs = siglist; sigs->signm; sigs++) FOREACH_SIGNAL(sigs, 0) {
if (sigs->signo == no) if (sigs->signo == no)
return sigs->signm; return sigs->signm;
}
return 0; return 0;
} }
@ -1415,7 +1421,7 @@ sig_list(void)
VALUE h = rb_hash_new(); VALUE h = rb_hash_new();
const struct signals *sigs; const struct signals *sigs;
for (sigs = siglist; sigs->signm; sigs++) { FOREACH_SIGNAL(sigs, 0) {
rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo)); rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo));
} }
return h; return h;