Skip to content

Commit

Permalink
Make sure that String::c_str() unshares before clamping. Fixes #793
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed Mar 25, 2011
1 parent e906a2e commit 2675eb8
Show file tree
Hide file tree
Showing 40 changed files with 90 additions and 84 deletions.
2 changes: 1 addition & 1 deletion vm/builtin/bignum.cpp
Expand Up @@ -1307,7 +1307,7 @@ namespace rubinius {

void Bignum::Info::show(STATE, Object* self, int level) {
Bignum* b = as<Bignum>(self);
std::cout << b->to_s(state, Fixnum::from(10))->c_str() << std::endl;
std::cout << b->to_s(state, Fixnum::from(10))->c_str(state) << std::endl;
}

void Bignum::Info::show_simple(STATE, Object* self, int level) {
Expand Down
4 changes: 2 additions & 2 deletions vm/builtin/compiledmethod.cpp
Expand Up @@ -175,7 +175,7 @@ namespace rubinius {
}

if(state->shared.config.jit_show_compiling) {
std::cout << "[[[ JIT compiling " << full_name(state)->c_str() << " ]]]\n";
std::cout << "[[[ JIT compiling " << full_name(state)->c_str(state) << " ]]]\n";
}

LLVMState* ls = LLVMState::get(state);
Expand All @@ -201,7 +201,7 @@ namespace rubinius {
}

if(state->shared.config.jit_show_compiling) {
std::cout << "[[[ JIT queueing " << full_name(state)->c_str() << " ]]]\n";
std::cout << "[[[ JIT queueing " << full_name(state)->c_str(state) << " ]]]\n";
}

LLVMState::get(state)->compile_soon(state, this);
Expand Down
4 changes: 2 additions & 2 deletions vm/builtin/dir.cpp
Expand Up @@ -54,10 +54,10 @@ namespace rubinius {
Object* Dir::open(STATE, String* path) {
if(os_) closedir(os_);

os_ = opendir(path->c_str());
os_ = opendir(path->c_str(state));

if(!os_) {
Exception::errno_error(state, "Unable to open directory", errno, path->c_str());
Exception::errno_error(state, "Unable to open directory", errno, path->c_str(state));
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions vm/builtin/exception.cpp
Expand Up @@ -48,11 +48,11 @@ namespace rubinius {
}
}

const char* Exception::message_c_str() {
const char* Exception::message_c_str(STATE) {
if(message()->nil_p()) return "<no message>";

if(String* str = try_as<String>(message())) {
return str->c_str();
return str->c_str(state);
}

return "<non-String Exception message>";
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/exception.hpp
Expand Up @@ -42,7 +42,7 @@ namespace rubinius {

void print_locations(STATE);

const char* message_c_str();
const char* message_c_str(STATE);

static Exception* make_exception(STATE, Class* exc_class, const char* message);
static Exception* make_type_error(STATE, object_type type, Object* object,
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/ffi_pointer.cpp
Expand Up @@ -453,7 +453,7 @@ namespace rubinius {
* internal pointer to the string means that when the string
* moves, the data will point at the wrong place. Probably need to
* copy the string data instead */
result = str->c_str();
result = str->c_str(state);
}
WRITE(const char*, result);
break;
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/float.cpp
Expand Up @@ -265,7 +265,7 @@ namespace rubinius {
String* Float::to_s_formatted(STATE, String* format) {
char str[FLOAT_TO_S_STRLEN];

size_t size = snprintf(str, FLOAT_TO_S_STRLEN, format->c_str(), val);
size_t size = snprintf(str, FLOAT_TO_S_STRLEN, format->c_str(state), val);

if(size >= FLOAT_TO_S_STRLEN) {
std::ostringstream msg;
Expand Down
4 changes: 2 additions & 2 deletions vm/builtin/heap_dump.cpp
Expand Up @@ -378,7 +378,7 @@ namespace rubinius {
// Seed it with the root objects.
walker.seed(gc_data);

int fd = open(path->c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0666);
int fd = open(path->c_str(state), O_CREAT | O_TRUNC | O_WRONLY, 0666);
if(fd < 0) return Qnil;

HeapDump dump(fd);
Expand All @@ -394,7 +394,7 @@ namespace rubinius {

dump.footer(state);

std::cout << "Heap dumped to " << path->c_str() << "\n";
std::cout << "Heap dumped to " << path->c_str(state) << "\n";
close(fd);

return Qnil;
Expand Down
8 changes: 4 additions & 4 deletions vm/builtin/io.cpp
Expand Up @@ -74,7 +74,7 @@ namespace rubinius {
}

Fixnum* IO::open(STATE, String* path, Fixnum* mode, Fixnum* perm) {
int fd = ::open(path->c_str(), mode->to_native(), perm->to_native());
int fd = ::open(path->c_str(state), mode->to_native(), perm->to_native());
return Fixnum::from(fd);
}

Expand Down Expand Up @@ -270,7 +270,7 @@ namespace rubinius {
Object* IO::reopen_path(STATE, String* path, Fixnum* mode) {
native_int cur_fd = to_fd();

int other_fd = ::open(path->c_str(), mode->to_native(), 0666);
int other_fd = ::open(path->c_str(state), mode->to_native(), 0666);

if(other_fd == -1) {
Exception::errno_error(state, "reopen");
Expand Down Expand Up @@ -649,7 +649,7 @@ namespace rubinius {
Object* IO::write_nonblock(STATE, String* buf) {
set_nonblock(state);

int n = ::write(descriptor_->to_native(), buf->c_str(), buf->size());
int n = ::write(descriptor_->to_native(), buf->c_str(state), buf->size());
if(n == -1) Exception::errno_error(state, "write_nonblock");
return Fixnum::from(n);
}
Expand Down Expand Up @@ -1002,7 +1002,7 @@ namespace rubinius {
}

Object* IO::fnmatch(STATE, String* pattern, String* path, Fixnum* flags) {
if(mri_fnmatch(pattern->c_str(), path->c_str(), flags->to_native())) {
if(mri_fnmatch(pattern->c_str(state), path->c_str(state), flags->to_native())) {
return Qtrue;
}

Expand Down
4 changes: 2 additions & 2 deletions vm/builtin/nativefunction.cpp
Expand Up @@ -795,7 +795,7 @@ namespace rubinius {
size = so->size();

char* data = ALLOCA_N(char, size + 1);
memcpy(data, so->c_str(), size);
memcpy(data, so->c_str(state), size);
data[size] = 0;
*tmp = data;
} else if(RTEST(obj->respond_to(state, state->symbol("to_ptr"), Qtrue))) {
Expand Down Expand Up @@ -845,7 +845,7 @@ namespace rubinius {
size = so->size();

char* data = ALLOCA_N(char, size + 1);
memcpy(data, so->c_str(), size);
memcpy(data, so->c_str(state), size);
data[size] = 0;
*tmp = data;
}
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/pack.cpp
Expand Up @@ -571,7 +571,7 @@ namespace rubinius {

String* Array::pack(STATE, String* directives, CallFrame* call_frame) {
// Ragel-specific variables
std::string d(directives->c_str(), directives->size());
std::string d(directives->c_str(state), directives->size());
const char *p = d.c_str();
const char *pe = p + d.size();
const char *eof = pe;
Expand Down
18 changes: 9 additions & 9 deletions vm/builtin/regexp.cpp
Expand Up @@ -206,7 +206,7 @@ namespace rubinius {
enc = current_encoding(state);
if(enc == onig_data->enc) return;

pat = (UChar*)source()->c_str();
pat = (UChar*)source()->c_str(state);
end = pat + source()->size();

int options = onig_data->options;
Expand Down Expand Up @@ -247,7 +247,7 @@ namespace rubinius {
OnigEncoding enc;
int err, num_names, kcode;

pat = (UChar*)pattern->c_str();
pat = (UChar*)pattern->c_str(state);
end = pat + pattern->size();

opts = options->to_native();
Expand Down Expand Up @@ -379,7 +379,7 @@ namespace rubinius {
region = onig_region_new();

max = string->size();
str = (UChar*)string->c_str();
str = (UChar*)string->c_str(state);

int* back_match = onig_data->int_map_backward;

Expand Down Expand Up @@ -434,7 +434,7 @@ namespace rubinius {
max = string->size();
native_int pos = start->to_native();

str = (UChar*)string->c_str();
str = (UChar*)string->c_str(state);
fin = str + max;

str += pos;
Expand Down Expand Up @@ -480,7 +480,7 @@ namespace rubinius {
max = string->size();
native_int pos = start->to_native();

str = (UChar*)string->c_str();
str = (UChar*)string->c_str(state);
fin = str + max;

str += pos;
Expand Down Expand Up @@ -523,7 +523,7 @@ namespace rubinius {
return String::create(state, 0, 0);
}

const char* str = source_->c_str();
const char* str = source_->c_str(state);
native_int sz = fin->to_native() - beg->to_native();

return String::create(state, str + beg->to_native(), sz);
Expand All @@ -536,7 +536,7 @@ namespace rubinius {
return String::create(state, 0, 0);
}

const char* str = source_->c_str();
const char* str = source_->c_str(state);
native_int sz = beg->to_native();

return String::create(state, str, sz);
Expand All @@ -549,7 +549,7 @@ namespace rubinius {
return String::create(state, 0, 0);
}

const char* str = source_->c_str();
const char* str = source_->c_str(state);
native_int sz = (native_int)source_->size() - fin->to_native();

return String::create(state, str + fin->to_native(), sz);
Expand All @@ -570,7 +570,7 @@ namespace rubinius {
return Qnil;
}

const char* str = source_->c_str();
const char* str = source_->c_str(state);
native_int sz = fin->to_native() - beg->to_native();

return String::create(state, str + beg->to_native(), sz);
Expand Down
16 changes: 11 additions & 5 deletions vm/builtin/string.cpp
Expand Up @@ -192,9 +192,15 @@ namespace rubinius {
return state->symbol(this);
}

const char* String::c_str() {
const char* String::c_str(STATE) {
char* c_string = (char*)byte_address();
c_string[size()] = 0;

if(c_string[size()] != 0) {
unshare(state);
// Read it again because unshare might change it.
c_string = (char*)byte_address();
c_string[size()] = 0;
}

return c_string;
}
Expand Down Expand Up @@ -681,11 +687,11 @@ namespace rubinius {
}

String* String::crypt(STATE, String* salt) {
return String::create(state, ::crypt(this->c_str(), salt->c_str()));
return String::create(state, ::crypt(this->c_str(state), salt->c_str(state)));
}

Integer* String::to_i(STATE, Fixnum* fix_base, Object* strict) {
const char* str = c_str();
const char* str = c_str(state);
int base = fix_base->to_native();
bool negative = false;
Integer* value = Fixnum::from(0);
Expand Down Expand Up @@ -1040,7 +1046,7 @@ namespace rubinius {

void String::Info::show(STATE, Object* self, int level) {
String* str = as<String>(self);
std::cout << "\"" << str->c_str() << "\"" << std::endl;
std::cout << "\"" << str->c_str(state) << "\"" << std::endl;
}

void String::Info::show_simple(STATE, Object* self, int level) {
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/string.hpp
Expand Up @@ -104,7 +104,7 @@ namespace rubinius {
// object's data is null clamped properly.
//
// NOTE: do not free() or realloc() this buffer.
const char* c_str();
const char* c_str(STATE);

void unshare(STATE);
hashval hash_string(STATE);
Expand Down
18 changes: 9 additions & 9 deletions vm/builtin/system.cpp
Expand Up @@ -91,10 +91,10 @@ namespace rubinius {
// unmarshal_data method works.
Object* System::compiledfile_load(STATE, String* path, Integer* version) {
if(!state->probe->nil_p()) {
state->probe->load_runtime(state, std::string(path->c_str()));
state->probe->load_runtime(state, std::string(path->c_str(state)));
}

std::ifstream stream(path->c_str());
std::ifstream stream(path->c_str(state));
if(!stream) {
return Primitives::failure();
}
Expand Down Expand Up @@ -150,7 +150,7 @@ namespace rubinius {

for(size_t i = 0; i < argc; i++) {
/* strdup should be OK. Trying to exec with strings containing NUL == bad. --rue */
argv[i] = strdup(as<String>(args->get(state, i))->c_str());
argv[i] = strdup(as<String>(args->get(state, i))->c_str(state));
}

void* old_handlers[NSIG];
Expand All @@ -161,7 +161,7 @@ namespace rubinius {
old_handlers[i] = (void*)signal(i, SIG_DFL);
}

(void)::execvp(path->c_str(), argv);
(void)::execvp(path->c_str(state), argv);

// UG. Disaster.
//
Expand All @@ -184,7 +184,7 @@ namespace rubinius {

if(pipe(fds) != 0) return Primitives::failure();

const char* c_str = str->c_str();
const char* c_str = str->c_str(state);

pid_t pid = fork();

Expand Down Expand Up @@ -392,7 +392,7 @@ namespace rubinius {
}

Object* System::vm_get_config_item(STATE, String* var) {
ConfigParser::Entry* ent = state->shared.user_variables.find(var->c_str());
ConfigParser::Entry* ent = state->shared.user_variables.find(var->c_str(state));
if(!ent) return Qnil;

if(ent->is_number()) {
Expand Down Expand Up @@ -486,7 +486,7 @@ namespace rubinius {
}

Object* System::vm_write_error(STATE, String* str) {
std::cerr << str->c_str() << std::endl;
std::cerr << str->c_str(state) << std::endl;
return Qnil;
}

Expand Down Expand Up @@ -912,7 +912,7 @@ namespace rubinius {
if(what->size() < 1) {
kcode::set(state, kcode::eAscii);
} else {
const char* str = what->c_str();
const char* str = what->c_str(state);

switch(str[0]) {
case 'E':
Expand Down Expand Up @@ -1025,7 +1025,7 @@ namespace rubinius {
struct passwd *pwd;
String* home = 0;

if((pwd = getpwnam(name->c_str()))) {
if((pwd = getpwnam(name->c_str(state)))) {
home = String::create(state, pwd->pw_dir);
} else {
home = nil<String>();
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/time.cpp
Expand Up @@ -199,7 +199,7 @@ namespace rubinius {
struct timespec ts = { seconds, 0 };

size_t chars = ::strftime_extended(str, MAX_STRFTIME_OUTPUT,
format->c_str(), &tm, &ts, is_gmt);
format->c_str(state), &tm, &ts, is_gmt);
str[MAX_STRFTIME_OUTPUT-1] = 0;

return String::create(state, str, chars);
Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/unpack.cpp
Expand Up @@ -560,7 +560,7 @@ namespace rubinius {

Array* String::unpack(STATE, String* directives) {
// Ragel-specific variables
std::string d(directives->c_str(), directives->size());
std::string d(directives->c_str(state), directives->size());
const char *p = d.c_str();
const char *pe = p + d.size();

Expand Down
2 changes: 1 addition & 1 deletion vm/capi/numeric.cpp
Expand Up @@ -21,7 +21,7 @@ extern "C" {
char chr;

if((str = try_as<String>(object)) && str->size() >= 1) {
chr = str->c_str()[0];
chr = str->c_str(env->state())[0];
} else {
chr = (char)(NUM2INT(obj) & 0xff);
}
Expand Down

0 comments on commit 2675eb8

Please sign in to comment.