Revision: 5231 http://trac.macosforge.org/projects/ruby/changeset/5231 Author: lsansonetti@apple.com Date: 2011-02-11 19:27:31 -0800 (Fri, 11 Feb 2011) Log Message: ----------- fix a race condition bug when generating internal class names where concurrent access would cause runtime problems Modified Paths: -------------- MacRuby/trunk/class.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2011-02-10 22:43:58 UTC (rev 5230) +++ MacRuby/trunk/class.c 2011-02-12 03:27:31 UTC (rev 5231) @@ -148,31 +148,19 @@ static VALUE rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass) { - char ocname[128]; - - if (name == NULL) { - static long anon_count = 1; - snprintf(ocname, sizeof ocname, "RBAnonymous%ld", ++anon_count); + char ocname[512] = { '\0' }; + if (!rb_vm_generate_objc_class_name(name, ocname, sizeof ocname)) { + goto no_more_classes; } - else { - if (objc_getClass(name) != NULL) { - long count = 1; - snprintf(ocname, sizeof ocname, "RB%s", name); - while (objc_getClass(ocname) != NULL) { - snprintf(ocname, sizeof ocname, "RB%s%ld", name, ++count); - } - } - else { - strncpy(ocname, name, sizeof ocname); - } - } if (super == 0) { super = rb_cObject; } Class ocklass = objc_allocateClassPair((Class)super, ocname, sizeof(id)); - assert(ocklass != NULL); + if (ocklass == NULL) { + goto no_more_classes; + } long version_flag = RCLASS_IS_RUBY_CLASS; if (flags == T_MODULE) { @@ -187,6 +175,9 @@ } return (VALUE)ocklass; + +no_more_classes: + rb_raise(rb_eRuntimeError, "can't create new classes"); } VALUE Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2011-02-10 22:43:58 UTC (rev 5230) +++ MacRuby/trunk/vm.cpp 2011-02-12 03:27:31 UTC (rev 5231) @@ -4799,6 +4799,37 @@ return GET_VM()->get_current_class(); } +extern "C" +bool +rb_vm_generate_objc_class_name(const char *name, char *buf, size_t buflen) +{ + RoxorCoreLock lock; + + if (name == NULL) { + static unsigned long anon_count = 1; + if (anon_count == ULONG_MAX) { + return false; + } + snprintf(buf, buflen, "RBAnonymous%ld", ++anon_count); + } + else { + if (objc_getClass(name) != NULL) { + unsigned long count = 1; + snprintf(buf, buflen, "RB%s", name); + while (objc_getClass(buf) != NULL) { + if (count == ULONG_MAX) { + return false; + } + snprintf(buf, buflen, "RB%s%ld", name, ++count); + } + } + else { + strncpy(buf, name, buflen); + } + } + return true; +} + static VALUE builtin_ostub1(IMP imp, id self, SEL sel, int argc, VALUE *argv) { Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2011-02-10 22:43:58 UTC (rev 5230) +++ MacRuby/trunk/vm.h 2011-02-12 03:27:31 UTC (rev 5231) @@ -491,6 +491,9 @@ bool rb_vm_aot_feature_load(const char *name); +bool rb_vm_generate_objc_class_name(const char *name, char *buf, + size_t buflen); + void rb_vm_raise(VALUE exception); void rb_vm_raise_current_exception(void); VALUE rb_vm_current_exception(void);
participants (1)
-
source_changes@macosforge.org