process.c: use shell for reserved or special built-in
* process.c (rb_exec_fillarg): use shell if the first word is reserved or special built-in name. http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36049 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e6a6561121
commit
2d460925f2
@ -1,4 +1,8 @@
|
|||||||
Wed Jun 13 09:55:29 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Jun 13 09:56:29 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* process.c (rb_exec_fillarg): use shell if the first word is reserved
|
||||||
|
or special built-in name.
|
||||||
|
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
|
||||||
|
|
||||||
* process.c (rb_exec_fillarg): treat '=' only in the first word. if
|
* process.c (rb_exec_fillarg): treat '=' only in the first word. if
|
||||||
the first word does not contain '=', it is the command name and
|
the first word does not contain '=', it is the command name and
|
||||||
|
78
process.c
78
process.c
@ -79,6 +79,8 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define numberof(array) (int)(sizeof(array)/sizeof((array)[0]))
|
||||||
|
|
||||||
#if defined(HAVE_TIMES) || defined(_WIN32)
|
#if defined(HAVE_TIMES) || defined(_WIN32)
|
||||||
static VALUE rb_cProcessTms;
|
static VALUE rb_cProcessTms;
|
||||||
#endif
|
#endif
|
||||||
@ -1824,6 +1826,20 @@ rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, V
|
|||||||
return prog;
|
return prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct string_part {
|
||||||
|
const char *ptr;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_posix_sh(const void *key, const void *el)
|
||||||
|
{
|
||||||
|
const struct string_part *word = key;
|
||||||
|
int ret = strncmp(word->ptr, el, word->len);
|
||||||
|
if (!ret && ((const char *)el)[word->len]) ret = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, struct rb_exec_arg *e)
|
rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, struct rb_exec_arg *e)
|
||||||
{
|
{
|
||||||
@ -1850,10 +1866,40 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, str
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (e->use_shell) {
|
if (e->use_shell) {
|
||||||
|
static const char posix_sh_cmds[][8] = {
|
||||||
|
"!", /* reserved */
|
||||||
|
".", /* special built-in */
|
||||||
|
"break", /* special built-in */
|
||||||
|
"case", /* reserved */
|
||||||
|
"colon", /* special built-in */
|
||||||
|
"continue", /* special built-in */
|
||||||
|
"do", /* reserved */
|
||||||
|
"done", /* reserved */
|
||||||
|
"elif", /* reserved */
|
||||||
|
"else", /* reserved */
|
||||||
|
"esac", /* reserved */
|
||||||
|
"eval", /* special built-in */
|
||||||
|
"exec", /* special built-in */
|
||||||
|
"exit", /* special built-in */
|
||||||
|
"export", /* special built-in */
|
||||||
|
"fi", /* reserved */
|
||||||
|
"for", /* reserved */
|
||||||
|
"if", /* reserved */
|
||||||
|
"in", /* reserved */
|
||||||
|
"readonly", /* special built-in */
|
||||||
|
"return", /* special built-in */
|
||||||
|
"set", /* special built-in */
|
||||||
|
"shift", /* special built-in */
|
||||||
|
"then", /* reserved */
|
||||||
|
"times", /* special built-in */
|
||||||
|
"trap", /* special built-in */
|
||||||
|
"unset", /* special built-in */
|
||||||
|
"until", /* reserved */
|
||||||
|
"while", /* reserved */
|
||||||
|
};
|
||||||
const char *p;
|
const char *p;
|
||||||
int first = 1;
|
struct string_part first = {0, 0};
|
||||||
int has_meta = 0;
|
int has_meta = 0;
|
||||||
int has_nonspace = 0;
|
|
||||||
/*
|
/*
|
||||||
* meta characters:
|
* meta characters:
|
||||||
*
|
*
|
||||||
@ -1879,18 +1925,32 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, str
|
|||||||
* % (used in Parameter Expansion)
|
* % (used in Parameter Expansion)
|
||||||
*/
|
*/
|
||||||
for (p = RSTRING_PTR(prog); *p; p++) {
|
for (p = RSTRING_PTR(prog); *p; p++) {
|
||||||
if (!has_nonspace && *p != ' ' && *p != '\t')
|
if (*p == ' ' || *p == '\t') {
|
||||||
has_nonspace = 1;
|
if (first.ptr && !first.len) first.len = p - first.ptr;
|
||||||
if (has_nonspace && (*p == ' ' || *p == '\t'))
|
}
|
||||||
first = 0;
|
else {
|
||||||
|
if (!first.ptr) first.ptr = p;
|
||||||
|
}
|
||||||
if (!has_meta && strchr("*?{}[]<>()~&|\\$;'`\"\n#", *p))
|
if (!has_meta && strchr("*?{}[]<>()~&|\\$;'`\"\n#", *p))
|
||||||
has_meta = 1;
|
has_meta = 1;
|
||||||
if (first && *p == '=')
|
if (!first.len) {
|
||||||
|
if (*p == '=') {
|
||||||
has_meta = 1;
|
has_meta = 1;
|
||||||
if (has_nonspace && has_meta)
|
}
|
||||||
|
else if (*p == '/') {
|
||||||
|
first.len = SIZE_T_MAX; /* longer than any posix_sh_cmds */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (has_meta)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (has_nonspace && !has_meta) {
|
if (!has_meta && first.ptr) {
|
||||||
|
if (!first.len) first.len = p - first.ptr;
|
||||||
|
if (first.len > 0 && first.len <= sizeof(posix_sh_cmds[0]) &&
|
||||||
|
bsearch(&first, posix_sh_cmds, numberof(posix_sh_cmds), sizeof(posix_sh_cmds[0]), compare_posix_sh))
|
||||||
|
has_meta = 1;
|
||||||
|
}
|
||||||
|
if (!has_meta) {
|
||||||
/* avoid shell since no shell meta charactor found. */
|
/* avoid shell since no shell meta charactor found. */
|
||||||
e->use_shell = 0;
|
e->use_shell = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user