summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--eval.c4
-rw-r--r--ext/dbm/dbm.c2
-rw-r--r--ext/gdbm/gdbm.c3
-rw-r--r--ext/sdbm/init.c2
-rw-r--r--lib/mathn.rb85
-rw-r--r--pack.c2
-rw-r--r--string.c9
8 files changed, 81 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 71822551d9..c614807ff7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Nov 15 00:33:40 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_clear): avoid revealing NULL pointer.
+ [ruby-dev:24766]
+
+ * string.c (str_gsub): add paranoid check. [ruby-dev:24827]
+
+ * string.c (str_mod_check): check frozen status as well.
+ [ruby-dev:24801]
+
Sun Nov 14 18:59:03 2004 Tanaka Akira <akr@m17n.org>
* process.c (proc_getrlimit): new function for Process.getrlimit.
@@ -13,6 +23,11 @@ Sun Nov 14 13:27:03 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/pp.rb (PP#object_address_group): remove odd number of 'f'
prefixed to negative address.
+Sun Nov 14 10:48:21 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/mathn.rb (Integer::gcd2): faster implementation by
+ <erlercw@siu.edu>. [ruby-talk:120232]
+
Sun Nov 14 08:46:33 2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
* test/logger/test_logger.rb: Logger just expects
@@ -38,6 +53,11 @@ Fri Nov 12 14:08:01 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: ditto
+Fri Nov 12 00:31:05 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/gdbm/gdbm.c (fgdbm_store): StringValue() may alter string
+ pointer. [ruby-dev:24783]
+
Thu Nov 11 17:58:19 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* dir.c (rb_glob): should have called rb_glob_caller().
diff --git a/eval.c b/eval.c
index da82e0ea8b..8bef0bcdd4 100644
--- a/eval.c
+++ b/eval.c
@@ -4686,6 +4686,10 @@ rb_yield_0(val, self, klass, flags, avalue)
POP_TAG();
if (state) goto pop_state;
}
+ else if (lambda && RARRAY(val)->len != 0) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
+ RARRAY(val)->len);
+ }
if (!node) {
state = 0;
goto pop_state;
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index c4f8b2b3f5..9dabca0ca1 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -462,11 +462,11 @@ fdbm_store(obj, keystr, valstr)
fdbm_modify(obj);
keystr = rb_obj_as_string(keystr);
+ valstr = rb_obj_as_string(valstr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- valstr = rb_obj_as_string(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c
index 49c86149e2..e905dad91b 100644
--- a/ext/gdbm/gdbm.c
+++ b/ext/gdbm/gdbm.c
@@ -566,10 +566,11 @@ fgdbm_store(obj, keystr, valstr)
rb_gdbm_modify(obj);
StringValue(keystr);
+ StringValue(valstr);
+
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- StringValue(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c
index eec9e71a3c..104faa0e4f 100644
--- a/ext/sdbm/init.c
+++ b/ext/sdbm/init.c
@@ -445,11 +445,11 @@ fsdbm_store(obj, keystr, valstr)
fdbm_modify(obj);
StringValue(keystr);
+ StringValue(valstr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- StringValue(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
diff --git a/lib/mathn.rb b/lib/mathn.rb
index aa2da885f3..ba8557cffc 100644
--- a/lib/mathn.rb
+++ b/lib/mathn.rb
@@ -17,24 +17,13 @@ require "matrix.rb"
class Integer
remove_method(:gcd2)
- def gcd2(int)
- a = self.abs
- b = int.abs
- a, b = b, a if a < b
-
- pd_a = a.prime_division
- pd_b = b.prime_division
-
- gcd = 1
- for pair in pd_a
- as = pd_b.assoc(pair[0])
- if as
- gcd *= as[0] ** [as[1], pair[1]].min
- end
- end
- return gcd
+ def gcd2(other)
+ min = self.abs
+ max = other.abs
+ min, max = max % min, min while min > 0
+ max
end
-
+
def Integer.from_prime_division(pd)
value = 1
for prime, index in pd
@@ -68,34 +57,54 @@ end
class Prime
include Enumerable
+ # These are included as class variables to cache them for later uses. If memory
+ # usage is a problem, they can be put in Prime#initialize as instance variables.
+ # There must be no primes between @@primes[-1] and @@next_to_check.
+ @@primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
+ # @@next_to_check % 6 must be 1.
+ @@next_to_check = 103 # @@primes[-1] - @@primes[-1] % 6 + 7
+ @@ulticheck_index = 3 # @@primes.index(@@primes.reverse.find {|n|
+ # n < Math.sqrt(@@next_to_check) })
+ @@ulticheck_next_squared = 121 # @@primes[@@ulticheck_index + 1] ** 2
+
+ class << self
+ # Return the prime cache.
+ def cache
+ return @@primes
+ end
+ alias primes cache
+ alias primes_so_far cache
+ end
+
def initialize
- @seed = 1
- @primes = []
- @counts = []
+ @index = -1
+ end
+
+ # Return primes given by this instance so far.
+ def primes
+ return @@primes[0, @index + 1]
end
+ alias primes_so_far primes
def succ
- i = -1
- size = @primes.size
- while i < size
- if i == -1
- @seed += 1
- i += 1
- else
- while @seed > @counts[i]
- @counts[i] += @primes[i]
- end
- if @seed != @counts[i]
- i += 1
- else
- i = -1
- end
+ @index += 1
+ while @index >= @@primes.length
+ # Only check for prime factors up to the square root of the potential primes,
+ # but without the performance hit of an actual square root calculation.
+ if @@next_to_check + 4 > @@ulticheck_next_squared
+ @@ulticheck_index += 1
+ @@ulticheck_next_squared = @@primes.at(@@ulticheck_index + 1) ** 2
end
+ # Only check numbers congruent to one and five, modulo six. All others
+ # are divisible by two or three. This also allows us to skip checking against
+ # two and three.
+ @@primes.push @@next_to_check if @@primes[2..@@ulticheck_index].find {|prime| @@next_to_check % prime == 0 }.nil?
+ @@next_to_check += 4
+ @@primes.push @@next_to_check if @@primes[2..@@ulticheck_index].find {|prime| @@next_to_check % prime == 0 }.nil?
+ @@next_to_check += 2
end
- @primes.push @seed
- @counts.push @seed + @seed
- return @seed
+ return @@primes[@index]
end
alias next succ
diff --git a/pack.c b/pack.c
index 9a83dc7041..4d927052d8 100644
--- a/pack.c
+++ b/pack.c
@@ -253,11 +253,11 @@ endian()
#undef ntohl
#undef htons
#undef htonl
+#endif
#define ntohs(x) swaps(x)
#define ntohl(x) swapl(x)
#define htons(x) swaps(x)
#define htonl(x) swapl(x)
-#endif
#define ntohf(x) swapf(x)
#define ntohd(x) swapd(x)
#define htonf(x) swapf(x)
diff --git a/string.c b/string.c
index 3df8fb9555..6ebbf9289d 100644
--- a/string.c
+++ b/string.c
@@ -45,7 +45,7 @@ str_mod_check(s, p, len)
char *p;
long len;
{
- if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {
+ if (RSTRING(s)->ptr != p || RSTRING(s)->len != len || OBJ_FROZEN(s)) {
rb_raise(rb_eRuntimeError, "string modified");
}
}
@@ -1962,9 +1962,7 @@ rb_str_sub_bang(argc, argv, str)
rb_match_busy(match);
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
- if (RSTRING(str)->ptr != p || RSTRING(str)->len != len) {
- rb_raise(rb_eRuntimeError, "string modified");
- }
+ str_mod_check(str, p, len);
rb_backref_set(match);
}
else {
@@ -2084,6 +2082,9 @@ str_gsub(argc, argv, str, bang)
rb_match_busy(match);
val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
str_mod_check(str, sp, slen);
+ if (val == dest) { /* paranoid chack [ruby-dev:24827] */
+ rb_raise(rb_eRuntimeError, "block should not cheat");
+ }
rb_backref_set(match);
}
else {