diff options
author | Fedor Indutny <fedor.indutny@gmail.com> | 2014-03-27 21:45:15 +0400 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2014-04-11 01:20:43 +0400 |
commit | 4c36f3e7e6108660fc3629d76036e40c1938f639 (patch) | |
tree | 094b5214eeae8c230550402a4fc5da821ec8e52c /src | |
parent | 525fad473bfafc2f44e1ab591152ca338fe45f2b (diff) | |
download | android-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.cc | 30 |
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); |