From 535c7777ac674ba86cf93c44824e07b0e23ea8c4 Mon Sep 17 00:00:00 2001 From: Timothy J Fontaine Date: Wed, 9 Apr 2014 17:33:33 -0700 Subject: [PATCH] src: replace usage of String::Utf8Value v8::String::Utf8Value previously could allow invalid surrogates when interpreting values. --- src/cares_wrap.cc | 8 +++-- src/fs_event_wrap.cc | 3 +- src/node.cc | 42 +++++++++++++------------- src/node_crypto.cc | 31 +++++++++---------- src/node_dtrace.cc | 6 ++-- src/node_file.cc | 37 ++++++++++++----------- src/node_stat_watcher.cc | 3 +- src/process_wrap.cc | 9 +++--- src/udp_wrap.cc | 9 +++--- src/util.h | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 158 insertions(+), 68 deletions(-) create mode 100644 src/util.h diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index b7ba828..321e144 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -31,6 +31,8 @@ #include "tree.h" #include "uv.h" +#include "util.h" + #if defined(__OpenBSD__) || defined(__MINGW32__) || defined(_MSC_VER) # include #else @@ -739,7 +741,7 @@ static Handle Query(const Arguments& args) { // object reference, causing wrap->GetObject() to return undefined. Local object = Local::New(wrap->GetObject()); - String::Utf8Value name(args[0]); + node::Utf8Value name(args[0]); int r = wrap->Send(*name); if (r) { @@ -768,7 +770,7 @@ static Handle QueryWithFamily(const Arguments& args) { // object reference, causing wrap->GetObject() to return undefined. Local object = Local::New(wrap->GetObject()); - String::Utf8Value name(args[0]); + node::Utf8Value name(args[0]); int family = args[1]->Int32Value(); int r = wrap->Send(*name, family); @@ -898,7 +900,7 @@ static Handle IsIP(const Arguments& args) { static Handle GetAddrInfo(const Arguments& args) { HandleScope scope; - String::Utf8Value hostname(args[0]); + node::Utf8Value hostname(args[0]); int fam = AF_UNSPEC; if (args[1]->IsInt32()) { diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index 7e3eb8c..fc54283 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -21,6 +21,7 @@ #include "node.h" #include "handle_wrap.h" +#include "util.h" #include @@ -97,7 +98,7 @@ Handle FSEventWrap::Start(const Arguments& args) { return ThrowException(Exception::TypeError(String::New("Bad arguments"))); } - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent, 0); if (r == 0) { diff --git a/src/node.cc b/src/node.cc index 5cb202f..4223973 100644 --- a/src/node.cc +++ b/src/node.cc @@ -82,6 +82,8 @@ typedef int mode_t; #include "node_script.h" #include "v8_typed_array.h" +#include "util.h" + using namespace v8; # ifdef __APPLE__ @@ -1102,7 +1104,7 @@ enum encoding ParseEncoding(Handle encoding_v, enum encoding _default) { if (!encoding_v->IsString()) return _default; - String::Utf8Value encoding(encoding_v); + node::Utf8Value encoding(encoding_v); if (strcasecmp(*encoding, "utf8") == 0) { return UTF8; @@ -1202,12 +1204,12 @@ void DisplayExceptionLine (TryCatch &try_catch) { if (!message.IsEmpty()) { // Print (filename):(line number): (message). - String::Utf8Value filename(message->GetScriptResourceName()); + node::Utf8Value filename(message->GetScriptResourceName()); const char* filename_string = *filename; int linenum = message->GetLineNumber(); fprintf(stderr, "%s:%i\n", filename_string, linenum); // Print line of source code. - String::Utf8Value sourceline(message->GetSourceLine()); + node::Utf8Value sourceline(message->GetSourceLine()); const char* sourceline_string = *sourceline; // Because of how node modules work, all scripts are wrapped with a @@ -1254,7 +1256,7 @@ static void ReportException(TryCatch &try_catch, bool show_line) { if (show_line) DisplayExceptionLine(try_catch); - String::Utf8Value trace(try_catch.StackTrace()); + node::Utf8Value trace(try_catch.StackTrace()); // range errors have a trace member set to undefined if (trace.length() > 0 && !try_catch.StackTrace()->IsUndefined()) { @@ -1269,11 +1271,11 @@ static void ReportException(TryCatch &try_catch, bool show_line) { !(er->ToObject()->Get(String::New("name"))->IsUndefined()); if (isErrorObject) { - String::Utf8Value name(er->ToObject()->Get(String::New("name"))); + node::Utf8Value name(er->ToObject()->Get(String::New("name"))); fprintf(stderr, "%s: ", *name); } - String::Utf8Value msg(!isErrorObject ? er + node::Utf8Value msg(!isErrorObject ? er : er->ToObject()->Get(String::New("message"))); fprintf(stderr, "%s\n", *msg); } @@ -1355,7 +1357,7 @@ static Handle Chdir(const Arguments& args) { return ThrowException(Exception::Error(String::New("Bad argument."))); } - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); uv_err_t r = uv_chdir(*path); @@ -1406,7 +1408,7 @@ static Handle Umask(const Arguments& args) { oct = args[0]->Uint32Value(); } else { oct = 0; - String::Utf8Value str(args[0]); + node::Utf8Value str(args[0]); // Parse the octal string. for (int i = 0; i < str.length(); i++) { @@ -1512,7 +1514,7 @@ static uid_t uid_by_name(Handle value) { if (value->IsUint32()) { return static_cast(value->Uint32Value()); } else { - String::Utf8Value name(value); + node::Utf8Value name(value); return uid_by_name(*name); } } @@ -1522,7 +1524,7 @@ static gid_t gid_by_name(Handle value) { if (value->IsUint32()) { return static_cast(value->Uint32Value()); } else { - String::Utf8Value name(value); + node::Utf8Value name(value); return gid_by_name(*name); } } @@ -1665,7 +1667,7 @@ static Handle InitGroups(const Arguments& args) { return ThrowTypeError("argument 2 must be a number or a string"); } - String::Utf8Value arg0(args[0]); + node::Utf8Value arg0(args[0]); gid_t extra_group; bool must_free; char* user; @@ -1826,7 +1828,7 @@ Handle DLOpen(const v8::Arguments& args) { } Local module = args[0]->ToObject(); // Cast - String::Utf8Value filename(args[1]); // Cast + node::Utf8Value filename(args[1]); // Cast if (exports_symbol.IsEmpty()) { exports_symbol = NODE_PSYMBOL("exports"); @@ -1842,7 +1844,7 @@ Handle DLOpen(const v8::Arguments& args) { return ThrowException(Exception::Error(errmsg)); } - String::Utf8Value path(args[1]); + node::Utf8Value path(args[1]); base = *path; /* Find the shared library filename within the full path. */ @@ -1961,7 +1963,7 @@ static Handle Binding(const Arguments& args) { HandleScope scope; Local module = args[0]->ToString(); - String::Utf8Value module_v(module); + node::Utf8Value module_v(module); node_module_struct* modp; if (binding_cache.IsEmpty()) { @@ -2020,7 +2022,7 @@ static void ProcessTitleSetter(Local property, Local value, const AccessorInfo& info) { HandleScope scope; - String::Utf8Value title(value); + node::Utf8Value title(value); // TODO: protect with a lock uv_set_process_title(*title); } @@ -2030,7 +2032,7 @@ static Handle EnvGetter(Local property, const AccessorInfo& info) { HandleScope scope; #ifdef __POSIX__ - String::Utf8Value key(property); + node::Utf8Value key(property); const char* val = getenv(*key); if (val) { return scope.Close(String::New(val)); @@ -2059,8 +2061,8 @@ static Handle EnvSetter(Local property, const AccessorInfo& info) { HandleScope scope; #ifdef __POSIX__ - String::Utf8Value key(property); - String::Utf8Value val(value); + node::Utf8Value key(property); + node::Utf8Value val(value); setenv(*key, *val, 1); #else // _WIN32 String::Value key(property); @@ -2080,7 +2082,7 @@ static Handle EnvQuery(Local property, const AccessorInfo& info) { HandleScope scope; #ifdef __POSIX__ - String::Utf8Value key(property); + node::Utf8Value key(property); if (getenv(*key)) { return scope.Close(Integer::New(0)); } @@ -2108,7 +2110,7 @@ static Handle EnvDeleter(Local property, const AccessorInfo& info) { HandleScope scope; #ifdef __POSIX__ - String::Utf8Value key(property); + node::Utf8Value key(property); if (!getenv(*key)) return False(); unsetenv(*key); // can't check return value, it's void on some platforms return True(); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 0ae1f8a..46faba2 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -26,6 +26,7 @@ #include "node.h" #include "node_buffer.h" #include "string_bytes.h" +#include "util.h" #include #ifdef _MSC_VER @@ -241,7 +242,7 @@ Handle SecureContext::Init(const Arguments& args) { OPENSSL_CONST SSL_METHOD *method = SSLv23_method(); if (args.Length() == 1 && args[0]->IsString()) { - String::Utf8Value sslmethod(args[0]); + node::Utf8Value sslmethod(args[0]); if (strcmp(*sslmethod, "SSLv2_method") == 0) { #ifndef OPENSSL_NO_SSL2 @@ -361,7 +362,7 @@ static BIO* LoadBIO (Handle v) { int r = -1; if (v->IsString()) { - String::Utf8Value s(v); + node::Utf8Value s(v); r = BIO_write(bio, *s, s.length()); } else if (Buffer::HasInstance(v)) { char* buffer_data = Buffer::Data(v); @@ -413,7 +414,7 @@ Handle SecureContext::SetKey(const Arguments& args) { BIO *bio = LoadBIO(args[0]); if (!bio) return False(); - String::Utf8Value passphrase(args[1]); + node::Utf8Value passphrase(args[1]); EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL, len == 1 ? NULL : *passphrase); @@ -643,7 +644,7 @@ Handle SecureContext::SetCiphers(const Arguments& args) { return ThrowException(Exception::TypeError(String::New("Bad parameter"))); } - String::Utf8Value ciphers(args[0]); + node::Utf8Value ciphers(args[0]); SSL_CTX_set_cipher_list(sc->ctx_, *ciphers); return True(); @@ -672,7 +673,7 @@ Handle SecureContext::SetSessionIdContext(const Arguments& args) { return ThrowException(Exception::TypeError(String::New("Bad parameter"))); } - String::Utf8Value sessionIdContext(args[0]); + node::Utf8Value sessionIdContext(args[0]); const unsigned char* sid_ctx = (const unsigned char*) *sessionIdContext; unsigned int sid_ctx_len = sessionIdContext.length(); @@ -1280,7 +1281,7 @@ Handle Connection::New(const Arguments& args) { if (is_server) { SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_); } else { - String::Utf8Value servername(args[2]); + node::Utf8Value servername(args[2]); SSL_set_tlsext_host_name(p->ssl_, *servername); } #endif @@ -2233,7 +2234,7 @@ class Cipher : public ObjectWrap { ssize_t key_written = DecodeWrite(key_buf, key_buf_len, args[1], BINARY); assert(key_written == key_buf_len); - String::Utf8Value cipherType(args[0]); + node::Utf8Value cipherType(args[0]); bool r = cipher->CipherInit(*cipherType, key_buf, key_buf_len); @@ -2284,7 +2285,7 @@ class Cipher : public ObjectWrap { ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY); assert(iv_written == iv_len); - String::Utf8Value cipherType(args[0]); + node::Utf8Value cipherType(args[0]); bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len); @@ -2543,7 +2544,7 @@ class Decipher : public ObjectWrap { ssize_t key_written = DecodeWrite(key_buf, key_len, args[1], BINARY); assert(key_written == key_len); - String::Utf8Value cipherType(args[0]); + node::Utf8Value cipherType(args[0]); bool r = cipher->DecipherInit(*cipherType, key_buf,key_len); @@ -2594,7 +2595,7 @@ class Decipher : public ObjectWrap { ssize_t iv_written = DecodeWrite(iv_buf, iv_len, args[2], BINARY); assert(iv_written == iv_len); - String::Utf8Value cipherType(args[0]); + node::Utf8Value cipherType(args[0]); bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len); @@ -2775,7 +2776,7 @@ class Hmac : public ObjectWrap { return ThrowException(exception); } - String::Utf8Value hashType(args[0]); + node::Utf8Value hashType(args[0]); bool r; @@ -2920,7 +2921,7 @@ class Hash : public ObjectWrap { "Must give hashtype string as argument"))); } - String::Utf8Value hashType(args[0]); + node::Utf8Value hashType(args[0]); Hash *hash = new Hash(); if (!hash->HashInit(*hashType)) { @@ -3094,7 +3095,7 @@ class Sign : public ObjectWrap { "Must give signtype string as argument"))); } - String::Utf8Value signType(args[0]); + node::Utf8Value signType(args[0]); bool r = sign->SignInit(*signType); @@ -3327,7 +3328,7 @@ class Verify : public ObjectWrap { "Must give verifytype string as argument"))); } - String::Utf8Value verifyType(args[0]); + node::Utf8Value verifyType(args[0]); bool r = verify->VerifyInit(*verifyType); @@ -3510,7 +3511,7 @@ class DiffieHellman : public ObjectWrap { String::New("No group name given"))); } - String::Utf8Value group_name(args[0]); + node::Utf8Value group_name(args[0]); modp_group* it = modp_groups; diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index 4b851e3..0b2d0f4 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -20,6 +20,8 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. +#include "util.h" + #ifdef HAVE_DTRACE #include "node_dtrace.h" #include @@ -66,7 +68,7 @@ using namespace v8; return (ThrowException(Exception::Error(String::New("expected " \ "object for " #obj " to contain string member " #member)))); \ } \ - String::Utf8Value _##member(obj->Get(String::New(#member))); \ + node::Utf8Value _##member(obj->Get(String::New(#member))); \ if ((*(const char **)valp = *_##member) == NULL) \ *(const char **)valp = ""; @@ -241,7 +243,7 @@ Handle DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { "object for request to contain string member headers")))); Local strfwdfor = headers->Get(String::New("x-forwarded-for")); - String::Utf8Value fwdfor(strfwdfor); + node::Utf8Value fwdfor(strfwdfor); if (!strfwdfor->IsString() || (req.forwardedFor = *fwdfor) == NULL) req.forwardedFor = const_cast(""); diff --git a/src/node_file.cc b/src/node_file.cc index f665b19..3c35e0b 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -24,6 +24,7 @@ #include "node_buffer.h" #include "node_stat_watcher.h" #include "req_wrap.h" +#include "util.h" #include #include @@ -403,7 +404,7 @@ static Handle Stat(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(stat, args[1], *path) @@ -420,7 +421,7 @@ static Handle LStat(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(lstat, args[1], *path) @@ -458,12 +459,12 @@ static Handle Symlink(const Arguments& args) { if (!args[0]->IsString()) return TYPE_ERROR("dest path must be a string"); if (!args[1]->IsString()) return TYPE_ERROR("src path must be a string"); - String::Utf8Value dest(args[0]); - String::Utf8Value path(args[1]); + node::Utf8Value dest(args[0]); + node::Utf8Value path(args[1]); int flags = 0; if (args[2]->IsString()) { - String::Utf8Value mode(args[2]); + node::Utf8Value mode(args[2]); if (strcmp(*mode, "dir") == 0) { flags |= UV_FS_SYMLINK_DIR; } else if (strcmp(*mode, "junction") == 0) { @@ -491,8 +492,8 @@ static Handle Link(const Arguments& args) { if (!args[0]->IsString()) return TYPE_ERROR("dest path must be a string"); if (!args[1]->IsString()) return TYPE_ERROR("src path must be a string"); - String::Utf8Value orig_path(args[0]); - String::Utf8Value new_path(args[1]); + node::Utf8Value orig_path(args[0]); + node::Utf8Value new_path(args[1]); if (args[2]->IsFunction()) { ASYNC_DEST_CALL(link, args[2], *new_path, *orig_path, *new_path) @@ -508,7 +509,7 @@ static Handle ReadLink(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(readlink, args[1], *path) @@ -527,8 +528,8 @@ static Handle Rename(const Arguments& args) { if (!args[0]->IsString()) return TYPE_ERROR("old path must be a string"); if (!args[1]->IsString()) return TYPE_ERROR("new path must be a string"); - String::Utf8Value old_path(args[0]); - String::Utf8Value new_path(args[1]); + node::Utf8Value old_path(args[0]); + node::Utf8Value new_path(args[1]); if (args[2]->IsFunction()) { ASYNC_DEST_CALL(rename, args[2], *new_path, *old_path, *new_path) @@ -598,7 +599,7 @@ static Handle Unlink(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(unlink, args[1], *path) @@ -614,7 +615,7 @@ static Handle RMDir(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(rmdir, args[1], *path) @@ -631,7 +632,7 @@ static Handle MKDir(const Arguments& args) { return THROW_BAD_ARGS; } - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); int mode = static_cast(args[1]->Int32Value()); if (args[2]->IsFunction()) { @@ -648,7 +649,7 @@ static Handle ReadDir(const Arguments& args) { if (args.Length() < 1) return TYPE_ERROR("path required"); if (!args[0]->IsString()) return TYPE_ERROR("path must be a string"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); if (args[1]->IsFunction()) { ASYNC_CALL(readdir, args[1], *path, 0 /*flags*/) @@ -686,7 +687,7 @@ static Handle Open(const Arguments& args) { if (!args[1]->IsInt32()) return TYPE_ERROR("flags must be an int"); if (!args[2]->IsInt32()) return TYPE_ERROR("mode must be an int"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); int flags = args[1]->Int32Value(); int mode = static_cast(args[2]->Int32Value()); @@ -826,7 +827,7 @@ static Handle Chmod(const Arguments& args) { if(args.Length() < 2 || !args[0]->IsString() || !args[1]->IsInt32()) { return THROW_BAD_ARGS; } - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); int mode = static_cast(args[1]->Int32Value()); if(args[2]->IsFunction()) { @@ -873,7 +874,7 @@ static Handle Chown(const Arguments& args) { if (!args[1]->IsUint32()) return TYPE_ERROR("uid must be an unsigned int"); if (!args[2]->IsUint32()) return TYPE_ERROR("gid must be an unsigned int"); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); uv_uid_t uid = static_cast(args[1]->Uint32Value()); uv_gid_t gid = static_cast(args[2]->Uint32Value()); @@ -924,7 +925,7 @@ static Handle UTimes(const Arguments& args) { if (!args[1]->IsNumber()) return TYPE_ERROR("atime must be a number"); if (!args[2]->IsNumber()) return TYPE_ERROR("mtime must be a number"); - const String::Utf8Value path(args[0]); + const node::Utf8Value path(args[0]); const double atime = static_cast(args[1]->NumberValue()); const double mtime = static_cast(args[2]->NumberValue()); diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index c3f668c..fd3e5d1 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -20,6 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #include "node_stat_watcher.h" +#include "util.h" #include #include @@ -104,7 +105,7 @@ Handle StatWatcher::Start(const Arguments& args) { HandleScope scope; StatWatcher* wrap = ObjectWrap::Unwrap(args.Holder()); - String::Utf8Value path(args[0]); + node::Utf8Value path(args[0]); const bool persistent = args[1]->BooleanValue(); const uint32_t interval = args[2]->Uint32Value(); diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 784300f..ac63e4b 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -25,6 +25,7 @@ #include "tty_wrap.h" #include "tcp_wrap.h" #include "udp_wrap.h" +#include "util.h" #include #include @@ -187,7 +188,7 @@ class ProcessWrap : public HandleWrap { // options.file Local file_v = js_options->Get(String::NewSymbol("file")); - String::Utf8Value file(file_v->IsString() ? file_v : Local()); + node::Utf8Value file(file_v->IsString() ? file_v : Local()); if (file.length() > 0) { options.file = *file; } else { @@ -202,7 +203,7 @@ class ProcessWrap : public HandleWrap { // Heap allocate to detect errors. +1 is for NULL. options.args = new char*[argc + 1]; for (int i = 0; i < argc; i++) { - String::Utf8Value arg(js_argv->Get(i)); + node::Utf8Value arg(js_argv->Get(i)); options.args[i] = strdup(*arg); } options.args[argc] = NULL; @@ -210,7 +211,7 @@ class ProcessWrap : public HandleWrap { // options.cwd Local cwd_v = js_options->Get(String::NewSymbol("cwd")); - String::Utf8Value cwd(cwd_v->IsString() ? cwd_v : Local()); + node::Utf8Value cwd(cwd_v->IsString() ? cwd_v : Local()); if (cwd.length() > 0) { options.cwd = *cwd; } @@ -222,7 +223,7 @@ class ProcessWrap : public HandleWrap { int envc = env->Length(); options.env = new char*[envc + 1]; // Heap allocated to detect errors. for (int i = 0; i < envc; i++) { - String::Utf8Value pair(env->Get(i)); + node::Utf8Value pair(env->Get(i)); options.env[i] = strdup(*pair); } options.env[envc] = NULL; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index b33f4e8..31a4e78 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -25,6 +25,7 @@ #include "req_wrap.h" #include "handle_wrap.h" #include "udp_wrap.h" +#include "util.h" #include @@ -160,7 +161,7 @@ Handle UDPWrap::DoBind(const Arguments& args, int family) { // bind(ip, port, flags) assert(args.Length() == 3); - String::Utf8Value address(args[0]); + node::Utf8Value address(args[0]); const int port = args[1]->Uint32Value(); const int flags = args[2]->Uint32Value(); @@ -219,8 +220,8 @@ Handle UDPWrap::SetMembership(const Arguments& args, assert(args.Length() == 2); - String::Utf8Value address(args[0]); - String::Utf8Value iface(args[1]); + node::Utf8Value address(args[0]); + node::Utf8Value iface(args[1]); const char* iface_cstr = *iface; if (args[1]->IsUndefined() || args[1]->IsNull()) { @@ -271,7 +272,7 @@ Handle UDPWrap::DoSend(const Arguments& args, int family) { length); const unsigned short port = args[3]->Uint32Value(); - String::Utf8Value address(args[4]); + node::Utf8Value address(args[4]); switch (family) { case AF_INET: diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..0dbf7f4 --- /dev/null +++ b/src/util.h @@ -0,0 +1,78 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_UTIL_H_ +#define SRC_UTIL_H_ + +#include "v8.h" +#include "string_bytes.h" + +namespace node { + +class Utf8Value { + public: + explicit Utf8Value(v8::Handle value) + : length_(0), str_(NULL) { + if (value.IsEmpty()) + return; + + v8::Local val_ = value->ToString(); + + // Allocate enough space to include the null terminator + size_t len = StringBytes::StorageSize(val_, UTF8) + 1; + + char* str = static_cast(calloc(1, len)); + + int flags = WRITE_UTF8_FLAGS; + flags |= ~v8::String::NO_NULL_TERMINATION; + + length_ = val_->WriteUtf8(str, + len, + 0, + flags); + + str_ = reinterpret_cast(str); + } + + ~Utf8Value() { + free(str_); + } + + char* operator*() { + return str_; + }; + + const char* operator*() const { + return str_; + }; + + size_t length() { + return length_; + }; + + private: + size_t length_; + char* str_; +}; + +} // namespace node + +#endif // SRC_UTIL_H_ -- 2.7.4