summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2014-03-27 21:45:15 +0400
committerFedor Indutny <fedor@indutny.com>2014-04-11 01:20:43 +0400
commit4c36f3e7e6108660fc3629d76036e40c1938f639 (patch)
tree094b5214eeae8c230550402a4fc5da821ec8e52c /src
parent525fad473bfafc2f44e1ab591152ca338fe45f2b (diff)
downloadandroid-node-v8-4c36f3e7e6108660fc3629d76036e40c1938f639.tar.gz
android-node-v8-4c36f3e7e6108660fc3629d76036e40c1938f639.tar.bz2
android-node-v8-4c36f3e7e6108660fc3629d76036e40c1938f639.zip
buffer: truncate buffer after string decode
When our estimates for a storage size are higher than the actual length of decoded data, the destination buffer should be truncated. Otherwise `Buffer::Length` will give misleading information to C++ layer. fix #7365 Signed-off-by: Fedor Indutny <fedor@indutny.com>
Diffstat (limited to 'src')
-rw-r--r--src/smalloc.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/smalloc.cc b/src/smalloc.cc
index 1e9cc3621a..7b8b3e4473 100644
--- a/src/smalloc.cc
+++ b/src/smalloc.cc
@@ -504,6 +504,35 @@ bool HasExternalData(Environment* env, Local<Object> obj) {
}
+void AllocTruncate(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args.GetIsolate());
+ HandleScope scope(env->isolate());
+
+ Local<Object> obj = args[0].As<Object>();
+
+ // can't perform this check in JS
+ if (!obj->HasIndexedPropertiesInExternalArrayData())
+ return env->ThrowTypeError("object has no external array data");
+
+ char* data = static_cast<char*>(obj->GetIndexedPropertiesExternalArrayData());
+ enum ExternalArrayType array_type =
+ obj->GetIndexedPropertiesExternalArrayDataType();
+ int length = obj->GetIndexedPropertiesExternalArrayDataLength();
+
+ unsigned int new_len = args[1]->Uint32Value();
+ if (new_len > kMaxLength)
+ return env->ThrowRangeError("truncate length is bigger than kMaxLength");
+
+ if (static_cast<int>(new_len) > length)
+ return env->ThrowRangeError("truncate length is bigger than current one");
+
+ obj->SetIndexedPropertiesToExternalArrayData(data,
+ array_type,
+ static_cast<int>(new_len));
+}
+
+
+
class RetainedAllocInfo: public RetainedObjectInfo {
public:
explicit RetainedAllocInfo(Handle<Value> wrapper);
@@ -572,6 +601,7 @@ void Initialize(Handle<Object> exports,
NODE_SET_METHOD(exports, "alloc", Alloc);
NODE_SET_METHOD(exports, "dispose", AllocDispose);
+ NODE_SET_METHOD(exports, "truncate", AllocTruncate);
NODE_SET_METHOD(exports, "hasExternalData", HasExternalData);