Skip to content

Commit

Permalink
add tag v1_9_0_2
Browse files Browse the repository at this point in the history
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_2@17482 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
shyouhei committed Jun 20, 2008
2 parents e62d2cb + e1a45b1 commit 51b72c1
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 77 deletions.
39 changes: 39 additions & 0 deletions ChangeLog
@@ -1,3 +1,42 @@
Fri Jun 20 15:40:02 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>

* array.c (rb_ary_store, rb_ary_splice): not depend on unspecified
behavior at integer overflow.

* string.c (str_buf_cat): ditto.

Fri Jun 20 12:39:55 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>

* process.c (rb_detach_process): store detached process ID in the
thread local storage. moved from lib/open3.rb.

Fri Jun 20 11:57:46 2008 Yukihiro Matsumoto <matz@ruby-lang.org>

* string.c (rb_str_sub_bang): should preserve replacement points
since they may be altered in the yielded block.

Fri Jun 20 11:07:56 2008 Tanaka Akira <akr@fsij.org>

* string.c (rb_memhash): randomize hash to avoid algorithmic
complexity attacks.
(rb_str_hash): use rb_memhash.

* include/ruby/intern.h (rb_reset_random_seed): declared.

* thread.c (rb_thread_atfork): call rb_reset_random_seed.

* inits.c (rb_call_inits): call Init_RandomSeed at first.

* random.c (seed_initialized): defined.
(fill_random_seed): extracted from random_seed.
(make_seed_value): extracted from random_seed.
(rb_f_rand): initialize random seed at first.
(initial_seed): defined.
(Init_RandomSeed): defined.
(Init_RandomSeed2): defined.
(rb_reset_random_seed): defined.
(Init_Random): call Init_RandomSeed2.

Wed Jun 18 21:52:38 2008 URABE Shyouhei <shyouhei@ruby-lang.org>

* array.c (ary_new, rb_ary_initialize, rb_ary_store,
Expand Down
6 changes: 3 additions & 3 deletions array.c
Expand Up @@ -383,7 +383,7 @@ rb_ary_store(VALUE ary, long idx, VALUE val)
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
}
else if (new_capa >= ARY_MAX_SIZE - idx) {
if (new_capa >= ARY_MAX_SIZE - idx) {
new_capa = (ARY_MAX_SIZE - idx) / 2;
}
new_capa += idx;
Expand Down Expand Up @@ -986,10 +986,10 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
}
rb_ary_modify(ary);
if (beg >= RARRAY_LEN(ary)) {
len = beg + rlen;
if (len < 0 || len > ARY_MAX_SIZE) {
if (beg > ARY_MAX_SIZE - rlen) {
rb_raise(rb_eIndexError, "index %ld too big", beg);
}
len = beg + rlen;
if (len >= ARY_CAPA(ary)) {
RESIZE_CAPA(ary, len);
}
Expand Down
1 change: 1 addition & 0 deletions include/ruby/intern.h
Expand Up @@ -475,6 +475,7 @@ VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
/* random.c */
unsigned long rb_genrand_int32(void);
double rb_genrand_real(void);
void rb_reset_random_seed(void);
/* re.c */
#define rb_memcmp memcmp
int rb_memcicmp(const void*,const void*,long);
Expand Down
2 changes: 2 additions & 0 deletions inits.c
Expand Up @@ -38,6 +38,7 @@ void Init_Precision(void);
void Init_sym(void);
void Init_id(void);
void Init_process(void);
void Init_RandomSeed(void);
void Init_Random(void);
void Init_Range(void);
void Init_Rational(void);
Expand All @@ -58,6 +59,7 @@ void Init_Encoding(void);
void
rb_call_inits()
{
Init_RandomSeed();
Init_sym();
Init_id();
Init_var_tables();
Expand Down
1 change: 0 additions & 1 deletion lib/open3.rb
Expand Up @@ -66,7 +66,6 @@ def popen3(*cmd)

pid = spawn(*cmd, STDIN=>pw[0], STDOUT=>pr[1], STDERR=>pe[1])
wait_thr = Process.detach(pid)
wait_thr[:pid] = pid
pw[0].close
pr[1].close
pe[1].close
Expand Down
19 changes: 18 additions & 1 deletion process.c
Expand Up @@ -885,6 +885,20 @@ proc_waitall(void)
return result;
}

static inline ID
id_pid(void)
{
ID pid;
CONST_ID(pid, "pid");
return pid;
}

static VALUE
detach_process_pid(VALUE thread)
{
return rb_thread_local_aref(thread, id_pid());
}

static VALUE
detach_process_watcher(void *arg)
{
Expand All @@ -900,7 +914,10 @@ detach_process_watcher(void *arg)
VALUE
rb_detach_process(rb_pid_t pid)
{
return rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
rb_thread_local_aset(watcher, id_pid(), PIDT2NUM(pid));
rb_define_singleton_method(watcher, "pid", detach_process_pid, 0);
return watcher;
}


Expand Down
76 changes: 60 additions & 16 deletions random.c
Expand Up @@ -199,6 +199,7 @@ rb_genrand_real(void)
return genrand_real();
}

static int seed_initialized = 0;
static VALUE saved_seed = INT2FIX(0);

static VALUE
Expand Down Expand Up @@ -259,27 +260,21 @@ rand_init(VALUE vseed)
return old;
}

static VALUE
random_seed(void)
#define DEFAULT_SEED_LEN (4 * sizeof(long))

static void
fill_random_seed(char *ptr)
{
static int n = 0;
unsigned long *seed;
struct timeval tv;
int fd;
struct stat statbuf;
char *buf = (char*)ptr;

int seed_len;
BDIGIT *digits;
unsigned long *seed;
NEWOBJ(big, struct RBignum);
OBJSETUP(big, rb_cBignum, T_BIGNUM);
seed = (unsigned long *)buf;

seed_len = 4 * sizeof(long);
RBIGNUM_SET_SIGN(big, 1);
rb_big_resize((VALUE)big, seed_len / SIZEOF_BDIGITS + 1);
digits = RBIGNUM_DIGITS(big);
seed = (unsigned long *)RBIGNUM_DIGITS(big);

memset(digits, 0, RBIGNUM_LEN(big) * SIZEOF_BDIGITS);
memset(buf, 0, DEFAULT_SEED_LEN);

#ifdef S_ISCHR
if ((fd = open("/dev/urandom", O_RDONLY
Expand All @@ -294,7 +289,7 @@ random_seed(void)
#endif
)) >= 0) {
if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
read(fd, seed, seed_len);
read(fd, seed, DEFAULT_SEED_LEN);
}
close(fd);
}
Expand All @@ -305,13 +300,35 @@ random_seed(void)
seed[1] ^= tv.tv_sec;
seed[2] ^= getpid() ^ (n++ << 16);
seed[3] ^= (unsigned long)&seed;
}

static VALUE
make_seed_value(char *ptr)
{
BDIGIT *digits;
NEWOBJ(big, struct RBignum);
OBJSETUP(big, rb_cBignum, T_BIGNUM);

RBIGNUM_SET_SIGN(big, 1);
rb_big_resize((VALUE)big, DEFAULT_SEED_LEN / SIZEOF_BDIGITS + 1);
digits = RBIGNUM_DIGITS(big);

MEMCPY((char *)RBIGNUM_DIGITS(big), ptr, char, DEFAULT_SEED_LEN);

/* set leading-zero-guard if need. */
digits[RBIGNUM_LEN(big)-1] = digits[RBIGNUM_LEN(big)-2] <= 1 ? 1 : 0;

return rb_big_norm((VALUE)big);
}

static VALUE
random_seed(void)
{
char buf[DEFAULT_SEED_LEN];
fill_random_seed(buf);
return make_seed_value(buf);
}

/*
* call-seq:
* srand(number=0) => old_seed
Expand Down Expand Up @@ -453,6 +470,9 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
long val, max;

rb_scan_args(argc, argv, "01", &vmax);
if (!seed_initialized) {
rand_init(random_seed());
}
switch (TYPE(vmax)) {
case T_FLOAT:
if (RFLOAT_VALUE(vmax) <= LONG_MAX && RFLOAT_VALUE(vmax) >= LONG_MIN) {
Expand Down Expand Up @@ -499,10 +519,34 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
return LONG2NUM(val);
}

static char initial_seed[DEFAULT_SEED_LEN];

void
Init_RandomSeed(void)
{
fill_random_seed(initial_seed);
init_by_array((unsigned long*)initial_seed, DEFAULT_SEED_LEN/sizeof(unsigned long));
seed_initialized = 1;
}

static void
Init_RandomSeed2(void)
{
saved_seed = make_seed_value(initial_seed);
memset(initial_seed, 0, DEFAULT_SEED_LEN);
}

void
rb_reset_random_seed(void)
{
seed_initialized = 0;
saved_seed = INT2FIX(0);
}

void
Init_Random(void)
{
rand_init(random_seed());
Init_RandomSeed2();
rb_define_global_function("srand", rb_f_srand, -1);
rb_define_global_function("rand", rb_f_rand, -1);
rb_global_variable(&saved_seed);
Expand Down

0 comments on commit 51b72c1

Please sign in to comment.