Revision: 182 http://trac.macosforge.org/projects/ruby/changeset/182 Author: lsansonetti@apple.com Date: 2008-05-01 13:59:46 -0700 (Thu, 01 May 2008) Log Message: ----------- hopefully one of the last regression fixes Modified Paths: -------------- MacRuby/trunk/array.c MacRuby/trunk/dir.c MacRuby/trunk/ext/extmk.rb MacRuby/trunk/file.c MacRuby/trunk/hash.c MacRuby/trunk/load.c MacRuby/trunk/object.c MacRuby/trunk/parse.y MacRuby/trunk/sample/test.rb MacRuby/trunk/string.c Modified: MacRuby/trunk/array.c =================================================================== --- MacRuby/trunk/array.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/array.c 2008-05-01 20:59:46 UTC (rev 182) @@ -155,6 +155,16 @@ return ary; } +VALUE +rb_ary_untaint(VALUE ary) +{ + struct rb_objc_ary_struct *s; + s = rb_objc_ary_get_struct(ary); + if (s != NULL) + s->tainted = false; + return ary; +} + VALUE rb_ary_tainted(VALUE ary) { Modified: MacRuby/trunk/dir.c =================================================================== --- MacRuby/trunk/dir.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/dir.c 2008-05-01 20:59:46 UTC (rev 182) @@ -687,8 +687,9 @@ static void dir_chdir(VALUE path) { - if (chdir(RSTRING_PTR(path)) < 0) - rb_sys_fail(RSTRING_PTR(path)); + const char *cpath = RSTRING_CPTR(path); + if (chdir(cpath) < 0) + rb_sys_fail(cpath); } static int chdir_blocking = 0; @@ -719,6 +720,7 @@ chdir_thread = Qnil; dir_chdir(args->old_path); } + rb_objc_release(args->old_path); return Qnil; } Modified: MacRuby/trunk/ext/extmk.rb =================================================================== --- MacRuby/trunk/ext/extmk.rb 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/ext/extmk.rb 2008-05-01 20:59:46 UTC (rev 182) @@ -84,6 +84,7 @@ end def extmake(target) +GC.start print "#{$message} #{target}\n" $stdout.flush if $force_static or $static_ext[target] @@ -425,6 +426,8 @@ FileUtils::makedirs('ext') Dir::chdir('ext') +GC.start + hdrdir = $hdrdir $hdrdir = ($top_srcdir = relative_from(srcdir, $topdir = "..")) + "/include" exts.each do |d| Modified: MacRuby/trunk/file.c =================================================================== --- MacRuby/trunk/file.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/file.c 2008-05-01 20:59:46 UTC (rev 182) @@ -2845,7 +2845,7 @@ StringValue(fext); } FilePathStringValue(fname); - if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname))) + if (RSTRING_CLEN(fname) == 0 || !*(name = RSTRING_CPTR(fname))) return fname; name = skipprefix(name); #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC @@ -2876,7 +2876,7 @@ else if (!(p = strrdirsep(name))) { if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) { f = chompdirsep(name) - name; - if (f == RSTRING_LEN(fname)) return fname; + if (f == RSTRING_CLEN(fname)) return fname; } p = name; } Modified: MacRuby/trunk/hash.c =================================================================== --- MacRuby/trunk/hash.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/hash.c 2008-05-01 20:59:46 UTC (rev 182) @@ -323,14 +323,21 @@ VALUE rb_hash_taint(VALUE hash) { + rb_objc_hash_get_struct2(hash)->tainted = true; + return hash; +} + +VALUE +rb_hash_untaint(VALUE hash) +{ struct rb_objc_hash_struct *s; - - s = rb_objc_hash_get_struct2(hash); - s->tainted = true; - + s = rb_objc_hash_get_struct(hash); + if (s != NULL) + s->tainted = false; return hash; } + VALUE rb_hash_tainted(VALUE hash) { Modified: MacRuby/trunk/load.c =================================================================== --- MacRuby/trunk/load.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/load.c 2008-05-01 20:59:46 UTC (rev 182) @@ -264,7 +264,7 @@ VALUE iseq; th->parse_in_eval++; - node = (NODE *)rb_load_file(RSTRING_PTR(fname)); + node = (NODE *)rb_load_file(RSTRING_CPTR(fname)); th->parse_in_eval--; loaded = Qtrue; iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"), @@ -405,7 +405,7 @@ const char *loading; *path = 0; - ext = strrchr(ftptr = RSTRING_PTR(fname), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(fname), '.'); if (ext && !strchr(ext, '/')) { if (IS_RBEXT(ext)) { if (rb_feature_p(ftptr, ext, Qtrue, Qfalse, &loading)) { @@ -414,7 +414,7 @@ } if ((tmp = rb_find_file(fname)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); - ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, 0)) *path = tmp; return 'r'; @@ -426,12 +426,12 @@ if (loading) *path = rb_str_new2(loading); return 's'; } - tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname)); + tmp = rb_str_new(RSTRING_CPTR(fname), ext - RSTRING_CPTR(fname)); #ifdef DLEXT2 OBJ_FREEZE(tmp); if (rb_find_file_ext(&tmp, loadable_ext + 1)) { tmp = rb_file_expand_path(tmp, Qnil); - ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0)) *path = tmp; return 's'; @@ -441,7 +441,7 @@ OBJ_FREEZE(tmp); if ((tmp = rb_find_file(tmp)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); - ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0)) *path = tmp; return 's'; @@ -455,7 +455,7 @@ } if ((tmp = rb_find_file(fname)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); - ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0)) *path = tmp; return 's'; @@ -473,14 +473,14 @@ case 0: if (ft) break; - ftptr = RSTRING_PTR(tmp); + ftptr = RSTRING_CPTR(tmp); return rb_feature_p(ftptr, 0, Qfalse, Qtrue, 0); default: if (ft) break; case 1: - ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); + ext = strrchr(ftptr = RSTRING_CPTR(tmp), '.'); if (rb_feature_p(ftptr, ext, !--type, Qtrue, &loading) && !loading) break; *path = tmp; @@ -492,14 +492,14 @@ load_failed(VALUE fname) { rb_raise(rb_eLoadError, "no such file to load -- %s", - RSTRING_PTR(fname)); + RSTRING_CPTR(fname)); } static VALUE load_ext(VALUE path) { SCOPE_SET(NOEX_PUBLIC); - return (VALUE)dln_load(RSTRING_PTR(path)); + return (VALUE)dln_load(RSTRING_CPTR(path)); } VALUE @@ -526,7 +526,7 @@ rb_set_safe_level_force(safe); found = search_required(fname, &path); if (found) { - if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) { + if (!path || !(ftptr = load_lock(RSTRING_CPTR(path)))) { result = Qfalse; } else { @@ -611,7 +611,7 @@ ID id = rb_to_id(sym); Check_SafeStr(file); - rb_autoload(mod, id, RSTRING_PTR(file)); + rb_autoload(mod, id, RSTRING_CPTR(file)); return Qnil; } Modified: MacRuby/trunk/object.c =================================================================== --- MacRuby/trunk/object.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/object.c 2008-05-01 20:59:46 UTC (rev 182) @@ -736,6 +736,20 @@ rb_obj_untaint(VALUE obj) { rb_secure(3); +#if WITH_OBJC + if (rb_objc_is_non_native(obj)) { + int type = TYPE(obj); + if (type == T_ARRAY) + return rb_ary_untaint(obj); + else if (type == T_HASH) + return rb_hash_untaint(obj); + else if (type == T_STRING) + return rb_str_untaint(obj); + else + rb_raise(rb_eRuntimeError, "can't untaint pure objc object `%s'", + RSTRING_PTR(rb_inspect(obj))); + } +#endif if (OBJ_TAINTED(obj)) { if (OBJ_FROZEN(obj)) { rb_error_frozen("object"); Modified: MacRuby/trunk/parse.y =================================================================== --- MacRuby/trunk/parse.y 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/parse.y 2008-05-01 20:59:46 UTC (rev 182) @@ -9130,11 +9130,14 @@ if (st_lookup(global_symbols.sym_id, str, (st_data_t *)&id)) return id; #else - if (strlen(name) != len) { + long sname = strlen(name); + assert(len <= sname); + if (sname != len) { char *tmp = (char *)alloca(len + 1); - memcpy(tmp, name, len); - tmp[len] = '\0'; - name = tmp; + memcpy(tmp, name, len); + tmp[len] = '\0'; + m = name = tmp; + e = m + len; } SEL name_hash = sel_registerName(name); id = (ID)CFDictionaryGetValue((CFDictionaryRef)global_symbols.sym_id, Modified: MacRuby/trunk/sample/test.rb =================================================================== --- MacRuby/trunk/sample/test.rb 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/sample/test.rb 2008-05-01 20:59:46 UTC (rev 182) @@ -1464,7 +1464,6 @@ test_check "string & char" "abcd" =~ /ab/ -=begin test_ok("abcd" == "abcd") test_ok("abcd" =~ /abcd/) test_ok("abcd" === "abcd") @@ -1492,7 +1491,6 @@ test_ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") test_ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") -=end $x = <<END; ABCD @@ -1882,7 +1880,6 @@ false end -=begin for script in Dir["#{dir}{lib,sample,ext,test}/**/*.rb"] unless valid_syntax? IO::read(script), script STDERR.puts script @@ -1890,7 +1887,6 @@ end end test_ok(!$bad) -=end test_check "const" TEST1 = 1 Modified: MacRuby/trunk/string.c =================================================================== --- MacRuby/trunk/string.c 2008-04-30 20:14:30 UTC (rev 181) +++ MacRuby/trunk/string.c 2008-05-01 20:59:46 UTC (rev 182) @@ -137,6 +137,10 @@ n = rb_objc_str_get_struct2(new); memcpy(n, s, sizeof(struct rb_objc_str_struct)); + if (n->cfdata != NULL) { + GC_WB(&n->cfdata, CFDataCreateMutableCopy(NULL, 0, (CFDataRef)n->cfdata)); + CFMakeCollectable(n->cfdata); + } } } @@ -163,17 +167,26 @@ s = rb_objc_str_get_struct2(str); if (s->cfdata == NULL) { CFDataRef data; + CFMutableDataRef mdata; + long len; data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)str, kCFStringEncodingUTF8, 0); if (data == NULL) return NULL; -#if 1 - GC_WB(&s->cfdata, (void *)CFDataCreateCopy(NULL, data)); + mdata = CFDataCreateMutableCopy(NULL, 0, data); + //assert(mdata != NULL); + //assert(CFEqual(data, mdata)); + //assert(CFDataGetLength(data) == CFStringGetLength((CFStringRef)str)); + len = CFDataGetLength(data); + /* This is a hack to make sure a sentinel byte is created at the end + * of the buffer. + */ + CFDataSetLength(mdata, len + 1); + CFDataSetLength(mdata, len); + //assert(strcmp(CFDataGetBytePtr(mdata), CFStringGetCStringPtr((CFStringRef)str, 0))==0); + GC_WB(&s->cfdata, mdata); CFRelease((CFTypeRef)data); -#else - GC_WB(&s->cfdata, (void *)data); -#endif - CFMakeCollectable((CFTypeRef)s->cfdata); + CFMakeCollectable(s->cfdata); } return s->cfdata; } @@ -181,12 +194,8 @@ char * rb_str_byteptr(VALUE str) { -#if 1 return (char *)CFDataGetMutableBytePtr( (CFMutableDataRef)rb_str_cfdata(str)); -#else - return (char *)CFDataGetBytePtr((CFDataRef)rb_str_cfdata(str)); -#endif } long @@ -223,9 +232,9 @@ CFRelease(bytestr); strptr = CFStringGetCStringPtr((CFStringRef)str, 0); if (strptr != NULL - && ((const char *)dataptr == strptr - || dataptr == NULL - || memcmp((const char *)dataptr, strptr, datalen) == 0)) { + && ((const char *)dataptr == strptr + || dataptr == NULL + || memcmp((const char *)dataptr, strptr, datalen) == 0)) { s->cfdata = NULL; } } @@ -255,6 +264,16 @@ } VALUE +rb_str_untaint(VALUE str) +{ + struct rb_objc_str_struct *s; + s = rb_objc_str_get_struct(str); + if (s != NULL) + s->tainted = false; + return str; +} + +VALUE rb_str_tainted(VALUE str) { struct rb_objc_str_struct *s; @@ -538,7 +557,9 @@ VALUE str; str = (VALUE)CFStringCreateMutable(NULL, 0); - if (klass != 0 && klass != rb_cString && klass != rb_cStringRuby + if (klass != 0 + && klass != rb_cString + && klass != rb_cStringRuby && klass != rb_cSymbol) *(Class *)str = RCLASS_OCID(klass); CFMakeCollectable((CFTypeRef)str); @@ -568,8 +589,13 @@ assert(datalen > 0); #if 1 - CFStringRef substr = CFStringCreateWithBytes(NULL, (const UInt8 *)dataptr, - datalen, kCFStringEncodingUTF8, false); + CFStringRef substr = CFStringCreateWithBytes/*NoCopy*/( + NULL, + (const UInt8 *)dataptr, + datalen, + kCFStringEncodingUTF8, + false/*, + kCFAllocatorNull*/); CFStringReplaceAll((CFMutableStringRef)str, substr); CFRelease(substr); #else @@ -612,11 +638,6 @@ } else { long slen; - char sentinel_char = 0; - if (ptr[len] != '\0') { - sentinel_char = ptr[len]; - ((char *)ptr)[len] = '\0'; - } slen = strlen(ptr); if (slen == len) { CFStringAppendCString((CFMutableStringRef)str, ptr, @@ -626,8 +647,6 @@ else { rb_objc_str_set_bytestring(str, ptr, len); } - if (sentinel_char != 0) - ((char *)ptr)[len] = sentinel_char; } } if (need_padding) @@ -968,11 +987,14 @@ VALUE rb_str_dup(VALUE str) { - VALUE dup = str_alloc(rb_obj_class(str)); #if WITH_OBJC + CFMutableStringRef copy = CFStringCreateMutableCopy(NULL, 0, + (CFStringRef)str); + CFMakeCollectable(copy); + return (VALUE)copy; +#if 0 struct rb_objc_str_struct *s = rb_objc_str_get_struct(str); if (s != NULL && s->cfdata != NULL) { -#if 1 rb_str_bytesync(str); if (rb_str_cfdata2(str) != NULL) { struct rb_objc_str_struct *s2 = rb_objc_str_get_struct2(dup); @@ -981,11 +1003,13 @@ GC_WB(&s2->cfdata, data); CFMakeCollectable(data); } -#endif } #endif +#else + VALUE dup = str_alloc(rb_obj_class(str)); rb_str_replace(dup, str); return dup; +#endif } @@ -1425,7 +1449,7 @@ char * rb_string_value_ptr(volatile VALUE *ptr) { - return RSTRING_PTR(rb_string_value(ptr)); + return (char *)RSTRING_CPTR(rb_string_value(ptr)); } #if WITH_OBJC @@ -1438,7 +1462,8 @@ : (const char *)CFDataGetBytePtr(data); } -long rb_str_clen(VALUE ptr) +long +rb_str_clen(VALUE ptr) { CFDataRef data = (CFDataRef)rb_str_cfdata2(ptr); return data == NULL