|
9 | 9 | #include "../streams/native-stream-source.h" |
10 | 10 |
|
11 | 11 | #include "encode.h" |
| 12 | +#include "jstypes.h" |
12 | 13 | #include "mozilla/Assertions.h" |
13 | 14 | #include "mozilla/ResultVariant.h" |
14 | 15 |
|
@@ -42,6 +43,35 @@ size_t compute_normalized_len(std::string_view src) { |
42 | 43 | return len; |
43 | 44 | } |
44 | 45 |
|
| 46 | +size_t compute_unencoded_normalized_len(JSContext *cx, JS::HandleString value) { |
| 47 | + auto linear = JS_EnsureLinearString(cx, value); |
| 48 | + auto len = JS::GetDeflatedUTF8StringLength(linear); |
| 49 | + size_t js_len = JS_GetStringLength(value); |
| 50 | + |
| 51 | + for (size_t i = 0; i < js_len; i++) { |
| 52 | + char16_t ch = 0; |
| 53 | + if (!JS_GetStringCharAt(cx, value, i, &ch)) { |
| 54 | + break; |
| 55 | + } |
| 56 | + if (ch == CR) { |
| 57 | + if (i+1 < js_len) { |
| 58 | + char16_t next = 0; |
| 59 | + if (JS_GetStringCharAt(cx, value, i + 1, &next)) { |
| 60 | + if (next == LF) { |
| 61 | + i += 1; |
| 62 | + // the character is already accounted for |
| 63 | + continue; |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | + len += 1; |
| 68 | + } else if (ch == LF) { |
| 69 | + len += 1; // CRLF |
| 70 | + } |
| 71 | + } |
| 72 | + return len; |
| 73 | +} |
| 74 | + |
45 | 75 | // Normalizes newlines in a string by replacing: |
46 | 76 | // - CR not followed by LF -> CRLF |
47 | 77 | // - LF not preceded by CR -> CRLF |
@@ -517,12 +547,11 @@ mozilla::Result<size_t, OutOfMemory> MultipartFormDataImpl::query_length(JSConte |
517 | 547 | total += 2 * crlf_len; |
518 | 548 |
|
519 | 549 | RootedValue value_str(cx, entry.value); |
520 | | - auto value = core::encode(cx, value_str); |
| 550 | + JS::RootedString value(cx, JS::ToString(cx, value_str)); |
521 | 551 | if (!value) { |
522 | 552 | return mozilla::Result<size_t, OutOfMemory>(OutOfMemory {}); |
523 | 553 | } |
524 | | - |
525 | | - total += compute_normalized_len(value); |
| 554 | + total += compute_unencoded_normalized_len(cx, value); |
526 | 555 | } else { |
527 | 556 | MOZ_ASSERT(File::is_instance(entry.value)); |
528 | 557 | RootedObject obj(cx, &entry.value.toObject()); |
|
0 commit comments