| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 93ba585 commit 5201cb0
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -350,10 +350,14 @@ function slowToString(encoding, start, end) { | |||
| 350 | 350 | ||
| 351 | 351 | ||
| 352 | 352 | Buffer.prototype.toString = function() { | |
| 353 | - const length = this.length | 0; | ||
| 354 | - if (arguments.length === 0) | ||
| 355 | - return this.utf8Slice(0, length); | ||
| 356 | - return slowToString.apply(this, arguments); | ||
| 353 | + if (arguments.length === 0) { | ||
| 354 | + var result = this.utf8Slice(0, this.length); | ||
| 355 | + } else { | ||
| 356 | + var result = slowToString.apply(this, arguments); | ||
| 357 | + } | ||
| 358 | + if (result === undefined) | ||
| 359 | + throw new Error('toString failed'); | ||
| 360 | + return result; | ||
| 357 | 361 | }; | |
| 358 | 362 | ||
| 359 | 363 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1024,6 +1024,10 @@ void Initialize(Handle<Object> target, | |||
| 1024 | 1024 | target->Set(env->context(), | |
| 1025 | 1025 | FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"), | |
| 1026 | 1026 | Integer::NewFromUnsigned(env->isolate(), kMaxLength)).FromJust(); | |
| 1027 | + | ||
| 1028 | + target->Set(env->context(), | ||
| 1029 | + FIXED_ONE_BYTE_STRING(env->isolate(), "kStringMaxLength"), | ||
| 1030 | + Integer::New(env->isolate(), String::kMaxLength)).FromJust(); | ||
| 1027 | 1031 | } | |
| 1028 | 1032 | ||
| 1029 | 1033 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,13 +22,14 @@ using v8::Local; | |||
| 22 | 22 | using v8::Object; | |
| 23 | 23 | using v8::String; | |
| 24 | 24 | using v8::Value; | |
| 25 | + using v8::MaybeLocal; | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 27 | 28 | template <typename ResourceType, typename TypeName> | |
| 28 | 29 | class ExternString: public ResourceType { | |
| 29 | 30 | public: | |
| 30 | 31 | ~ExternString() override { | |
| 31 | - delete[] data_; | ||
| 32 | + free(const_cast<TypeName*>(data_)); | ||
| 32 | 33 | isolate()->AdjustAmountOfExternalAllocatedMemory(-byte_length()); | |
| 33 | 34 | } | |
| 34 | 35 | ||
@@ -52,7 +53,11 @@ class ExternString: public ResourceType { | |||
| 52 | 53 | if (length == 0) | |
| 53 | 54 | return scope.Escape(String::Empty(isolate)); | |
| 54 | 55 | ||
| 55 | - TypeName* new_data = new TypeName[length]; | ||
| 56 | + TypeName* new_data = | ||
| 57 | + static_cast<TypeName*>(malloc(length * sizeof(*new_data))); | ||
| 58 | + if (new_data == nullptr) { | ||
| 59 | + return Local<String>(); | ||
| 60 | + } | ||
| 56 | 61 | memcpy(new_data, data, length * sizeof(*new_data)); | |
| 57 | 62 | ||
| 58 | 63 | return scope.Escape(ExternString<ResourceType, TypeName>::New(isolate, | |
@@ -72,10 +77,15 @@ class ExternString: public ResourceType { | |||
| 72 | 77 | ExternString* h_str = new ExternString<ResourceType, TypeName>(isolate, | |
| 73 | 78 | data, | |
| 74 | 79 | length); | |
| 75 | - Local<String> str = String::NewExternal(isolate, h_str); | ||
| 80 | + MaybeLocal<String> str = String::NewExternal(isolate, h_str); | ||
| 76 | 81 | isolate->AdjustAmountOfExternalAllocatedMemory(h_str->byte_length()); | |
| 77 | 82 | ||
| 78 | - return scope.Escape(str); | ||
| 83 | + if (str.IsEmpty()) { | ||
| 84 | + delete h_str; | ||
| 85 | + return Local<String>(); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + return scope.Escape(str.ToLocalChecked()); | ||
| 79 | 89 | } | |
| 80 | 90 | ||
| 81 | 91 | inline Isolate* isolate() const { return isolate_; } | |
@@ -765,11 +775,14 @@ Local<Value> StringBytes::Encode(Isolate* isolate, | |||
| 765 | 775 | ||
| 766 | 776 | case ASCII: | |
| 767 | 777 | if (contains_non_ascii(buf, buflen)) { | |
| 768 | - char* out = new char[buflen]; | ||
| 778 | + char* out = static_cast<char*>(malloc(buflen)); | ||
| 779 | + if (out == nullptr) { | ||
| 780 | + return Local<String>(); | ||
| 781 | + } | ||
| 769 | 782 | force_ascii(buf, out, buflen); | |
| 770 | 783 | if (buflen < EXTERN_APEX) { | |
| 771 | 784 | val = OneByteString(isolate, out, buflen); | |
| 772 | - delete[] out; | ||
| 785 | + free(out); | ||
| 773 | 786 | } else { | |
| 774 | 787 | val = ExternOneByteString::New(isolate, out, buflen); | |
| 775 | 788 | } | |
@@ -797,14 +810,17 @@ Local<Value> StringBytes::Encode(Isolate* isolate, | |||
| 797 | 810 | ||
| 798 | 811 | case BASE64: { | |
| 799 | 812 | size_t dlen = base64_encoded_size(buflen); | |
| 800 | - char* dst = new char[dlen]; | ||
| 813 | + char* dst = static_cast<char*>(malloc(dlen)); | ||
| 814 | + if (dst == nullptr) { | ||
| 815 | + return Local<String>(); | ||
| 816 | + } | ||
| 801 | 817 | ||
| 802 | 818 | size_t written = base64_encode(buf, buflen, dst, dlen); | |
| 803 | 819 | CHECK_EQ(written, dlen); | |
| 804 | 820 | ||
| 805 | 821 | if (dlen < EXTERN_APEX) { | |
| 806 | 822 | val = OneByteString(isolate, dst, dlen); | |
| 807 | - delete[] dst; | ||
| 823 | + free(dst); | ||
| 808 | 824 | } else { | |
| 809 | 825 | val = ExternOneByteString::New(isolate, dst, dlen); | |
| 810 | 826 | } | |
@@ -813,13 +829,16 @@ Local<Value> StringBytes::Encode(Isolate* isolate, | |||
| 813 | 829 | ||
| 814 | 830 | case HEX: { | |
| 815 | 831 | size_t dlen = buflen * 2; | |
| 816 | - char* dst = new char[dlen]; | ||
| 832 | + char* dst = static_cast<char*>(malloc(dlen)); | ||
| 833 | + if (dst == nullptr) { | ||
| 834 | + return Local<String>(); | ||
| 835 | + } | ||
| 817 | 836 | size_t written = hex_encode(buf, buflen, dst, dlen); | |
| 818 | 837 | CHECK_EQ(written, dlen); | |
| 819 | 838 | ||
| 820 | 839 | if (dlen < EXTERN_APEX) { | |
| 821 | 840 | val = OneByteString(isolate, dst, dlen); | |
| 822 | - delete[] dst; | ||
| 841 | + free(dst); | ||
| 823 | 842 | } else { | |
| 824 | 843 | val = ExternOneByteString::New(isolate, dst, dlen); | |
| 825 | 844 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -107,3 +107,69 @@ var PRE_3OF4_APEX = Math.ceil((EXTERN_APEX / 4) * 3) - RADIOS; | |||
| 107 | 107 | assert.equal(a, b); | |
| 108 | 108 | assert.equal(b, c); | |
| 109 | 109 | })(); | |
| 110 | + | ||
| 111 | + // v8 fails silently if string length > v8::String::kMaxLength | ||
| 112 | + (function() { | ||
| 113 | + // v8::String::kMaxLength defined in v8.h | ||
| 114 | + const kStringMaxLength = process.binding('buffer').kStringMaxLength; | ||
| 115 | + | ||
| 116 | + assert.throws(function() { | ||
| 117 | + new Buffer(kStringMaxLength + 1).toString(); | ||
| 118 | + }, /toString failed|Buffer allocation failed/); | ||
| 119 | + | ||
| 120 | + try { | ||
| 121 | + new Buffer(kStringMaxLength * 4); | ||
| 122 | + } catch(e) { | ||
| 123 | + assert.equal(e.message, 'Buffer allocation failed - process out of memory'); | ||
| 124 | + console.log( | ||
| 125 | + '1..0 # Skipped: intensive toString tests due to memory confinements'); | ||
| 126 | + return; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + assert.throws(function() { | ||
| 130 | + new Buffer(kStringMaxLength + 1).toString('ascii'); | ||
| 131 | + }, /toString failed/); | ||
| 132 | + | ||
| 133 | + assert.throws(function() { | ||
| 134 | + new Buffer(kStringMaxLength + 1).toString('utf8'); | ||
| 135 | + }, /toString failed/); | ||
| 136 | + | ||
| 137 | + assert.throws(function() { | ||
| 138 | + new Buffer(kStringMaxLength * 2 + 2).toString('utf16le'); | ||
| 139 | + }, /toString failed/); | ||
| 140 | + | ||
| 141 | + assert.throws(function() { | ||
| 142 | + new Buffer(kStringMaxLength + 1).toString('binary'); | ||
| 143 | + }, /toString failed/); | ||
| 144 | + | ||
| 145 | + assert.throws(function() { | ||
| 146 | + new Buffer(kStringMaxLength + 1).toString('base64'); | ||
| 147 | + }, /toString failed/); | ||
| 148 | + | ||
| 149 | + assert.throws(function() { | ||
| 150 | + new Buffer(kStringMaxLength + 1).toString('hex'); | ||
| 151 | + }, /toString failed/); | ||
| 152 | + | ||
| 153 | + var maxString = new Buffer(kStringMaxLength).toString(); | ||
| 154 | + assert.equal(maxString.length, kStringMaxLength); | ||
| 155 | + // Free the memory early instead of at the end of the next assignment | ||
| 156 | + maxString = undefined; | ||
| 157 | + | ||
| 158 | + maxString = new Buffer(kStringMaxLength).toString('binary'); | ||
| 159 | + assert.equal(maxString.length, kStringMaxLength); | ||
| 160 | + maxString = undefined; | ||
| 161 | + | ||
| 162 | + maxString = | ||
| 163 | + new Buffer(kStringMaxLength + 1).toString('binary', 1); | ||
| 164 | + assert.equal(maxString.length, kStringMaxLength); | ||
| 165 | + maxString = undefined; | ||
| 166 | + | ||
| 167 | + maxString = | ||
| 168 | + new Buffer(kStringMaxLength + 1).toString('binary', 0, kStringMaxLength); | ||
| 169 | + assert.equal(maxString.length, kStringMaxLength); | ||
| 170 | + maxString = undefined; | ||
| 171 | + | ||
| 172 | + maxString = new Buffer(kStringMaxLength + 2).toString('utf16le'); | ||
| 173 | + assert.equal(maxString.length, (kStringMaxLength + 2) / 2); | ||
| 174 | + maxString = undefined; | ||
| 175 | + })(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments