aboutsummaryrefslogtreecommitdiff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
authorRoy Frostig <[email protected]>2010-08-11 16:06:45 -0700
committerRoy Frostig <[email protected]>2010-08-11 16:06:45 -0700
commitf307688bf44404b371b91b3b2a67048088695fe1 (patch)
treecfd89b43e614588ea7ee35eebd8f83eec3f5fedf /src/rt/rust_builtin.cpp
parentFix reverse-indexing bug in _vec.init_fn. (diff)
downloadrust-f307688bf44404b371b91b3b2a67048088695fe1.tar.xz
rust-f307688bf44404b371b91b3b2a67048088695fe1.zip
Add native vec[u8] to str converter. Put in workaround for leak in str to vec[u8] converter. Add testcase exercising both. Drive-by fix a potential array-out-of-bounds write on rust_str buffers.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp87
1 files changed, 68 insertions, 19 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index d8d9b8d6..64b587c0 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -2,19 +2,6 @@
#include "rust_internal.h"
/* Native builtins. */
-extern "C" CDECL rust_str*
-str_alloc(rust_task *task, size_t n_bytes)
-{
- rust_dom *dom = task->dom;
- size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
- void *mem = dom->malloc(alloc);
- if (!mem) {
- task->fail(2);
- return NULL;
- }
- rust_str *st = new (mem) rust_str(dom, alloc, 1, (uint8_t const *)"");
- return st;
-}
extern "C" CDECL rust_str*
last_os_error(rust_task *task) {
@@ -109,6 +96,48 @@ vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts)
return vec;
}
+extern "C" CDECL void *
+vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset)
+{
+ return (void *)&v->data[ty->size * offset];
+}
+
+extern "C" CDECL size_t
+vec_len(rust_task *task, type_desc *ty, rust_vec *v)
+{
+ return v->fill / ty->size;
+}
+
+/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */
+static rust_str *
+str_alloc_with_data(rust_task *task,
+ size_t n_bytes,
+ size_t fill,
+ uint8_t const *d)
+{
+ rust_dom *dom = task->dom;
+ size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
+ void *mem = dom->malloc(alloc);
+ if (!mem)
+ return NULL;
+ rust_str *st = new (mem) rust_str(dom, alloc, fill, d);
+ return st;
+}
+
+extern "C" CDECL rust_str*
+str_alloc(rust_task *task, size_t n_bytes)
+{
+ rust_str *st = str_alloc_with_data(task,
+ n_bytes + 1, // +1 to fit at least ""
+ 1,
+ (uint8_t const *)"");
+ if (!st) {
+ task->fail(2);
+ return NULL;
+ }
+ return st;
+}
+
extern "C" CDECL char const *
str_buf(rust_task *task, rust_str *s)
{
@@ -121,17 +150,37 @@ str_byte_len(rust_task *task, rust_str *s)
return s->fill - 1; // -1 for the '\0' terminator.
}
-extern "C" CDECL void *
-vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset)
+extern "C" CDECL rust_str *
+str_from_vec(rust_task *task, rust_vec *v)
{
- return (void *)&v->data[ty->size * offset];
+ rust_str *st =
+ str_alloc_with_data(task,
+ v->fill + 1, // +1 to fit at least '\0'
+ v->fill,
+ v->fill ? (uint8_t const *)v->data : NULL);
+ if (!st) {
+ task->fail(2);
+ return NULL;
+ }
+ st->data[st->fill++] = '\0';
+ return st;
}
-extern "C" CDECL size_t
-vec_len(rust_task *task, type_desc *ty, rust_vec *v)
+/*
+extern "C" CDECL rust_str*
+str_alloc(rust_task *task, size_t n_bytes)
{
- return v->fill / ty->size;
+ rust_dom *dom = task->dom;
+ size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
+ void *mem = dom->malloc(alloc);
+ if (!mem) {
+ task->fail(2);
+ return NULL;
+ }
+ rust_str *st = new (mem) rust_str(dom, alloc, 1, (uint8_t const *)"");
+ return st;
}
+*/
extern "C" CDECL void *
rand_new(rust_task *task)