@@ -198,6 +198,13 @@ MaybeLocal<Value> ExternTwoByteString::NewSimpleFromCopy(Isolate* isolate, |
198 | 198 |
|
199 | 199 | } // anonymous namespace |
200 | 200 |
|
| 201 | +static size_t keep_buflen_in_range(size_t len) { |
| 202 | + if (len > static_cast<size_t>(std::numeric_limits<int>::max())) { |
| 203 | + return static_cast<size_t>(std::numeric_limits<int>::max()); |
| 204 | + } |
| 205 | + return len; |
| 206 | +} |
| 207 | + |
201 | 208 | size_t StringBytes::WriteUCS2( |
202 | 209 | Isolate* isolate, char* buf, size_t buflen, Local<String> str, int flags) { |
203 | 210 | uint16_t* const dst = reinterpret_cast<uint16_t*>(buf); |
@@ -243,7 +250,7 @@ size_t StringBytes::Write(Isolate* isolate, |
243 | 250 | enum encoding encoding) { |
244 | 251 | HandleScope scope(isolate); |
245 | 252 | size_t nbytes; |
246 | | - |
| 253 | + buflen = keep_buflen_in_range(buflen); |
247 | 254 | CHECK(val->IsString() == true); |
248 | 255 | Local<String> str = val.As<String>(); |
249 | 256 | String::ValueView input_view(isolate, str); |
@@ -516,6 +523,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate, |
516 | 523 | } |
517 | 524 |
|
518 | 525 | case ASCII: |
| 526 | + buflen = keep_buflen_in_range(buflen); |
519 | 527 | if (simdutf::validate_ascii_with_errors(buf, buflen).error) { |
520 | 528 | // The input contains non-ASCII bytes. |
521 | 529 | char* out = node::UncheckedMalloc(buflen); |
@@ -529,23 +537,23 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate, |
529 | 537 | return ExternOneByteString::NewFromCopy(isolate, buf, buflen, error); |
530 | 538 | } |
531 | 539 |
|
532 | | - case UTF8: |
533 | | - { |
534 | | - val = String::NewFromUtf8(isolate, |
535 | | - buf, |
536 | | - v8::NewStringType::kNormal, |
537 | | - buflen); |
538 | | - Local<String> str; |
539 | | - if (!val.ToLocal(&str)) { |
540 | | - *error = node::ERR_STRING_TOO_LONG(isolate); |
541 | | - } |
542 | | - return str; |
| 540 | + case UTF8: { |
| 541 | + buflen = keep_buflen_in_range(buflen); |
| 542 | + val = |
| 543 | + String::NewFromUtf8(isolate, buf, v8::NewStringType::kNormal, buflen); |
| 544 | + Local<String> str; |
| 545 | + if (!val.ToLocal(&str)) { |
| 546 | + *error = node::ERR_STRING_TOO_LONG(isolate); |
543 | 547 | } |
| 548 | + return str; |
| 549 | + } |
544 | 550 |
|
545 | 551 | case LATIN1: |
| 552 | + buflen = keep_buflen_in_range(buflen); |
546 | 553 | return ExternOneByteString::NewFromCopy(isolate, buf, buflen, error); |
547 | 554 |
|
548 | 555 | case BASE64: { |
| 556 | + buflen = keep_buflen_in_range(buflen); |
549 | 557 | size_t dlen = simdutf::base64_length_from_binary(buflen); |
550 | 558 | char* dst = node::UncheckedMalloc(dlen); |
551 | 559 | if (dst == nullptr) { |
@@ -560,6 +568,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate, |
560 | 568 | } |
561 | 569 |
|
562 | 570 | case BASE64URL: { |
| 571 | + buflen = keep_buflen_in_range(buflen); |
563 | 572 | size_t dlen = |
564 | 573 | simdutf::base64_length_from_binary(buflen, simdutf::base64_url); |
565 | 574 | char* dst = node::UncheckedMalloc(dlen); |
@@ -576,6 +585,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate, |
576 | 585 | } |
577 | 586 |
|
578 | 587 | case HEX: { |
| 588 | + buflen = keep_buflen_in_range(buflen); |
579 | 589 | size_t dlen = buflen * 2; |
580 | 590 | char* dst = node::UncheckedMalloc(dlen); |
581 | 591 | if (dst == nullptr) { |
@@ -589,6 +599,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate, |
589 | 599 | } |
590 | 600 |
|
591 | 601 | case UCS2: { |
| 602 | + buflen = keep_buflen_in_range(buflen); |
592 | 603 | size_t str_len = buflen / 2; |
593 | 604 | if constexpr (IsBigEndian()) { |
594 | 605 | uint16_t* dst = node::UncheckedMalloc<uint16_t>(str_len); |
|