Skip to content

Commit a927dab

Browse files
committed
fix(formData): Stop encoding values to calculate length
1 parent 4051ee1 commit a927dab

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

builtins/web/form-data/form-data-encoder.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "../streams/native-stream-source.h"
1010

1111
#include "encode.h"
12+
#include "jstypes.h"
1213
#include "mozilla/Assertions.h"
1314
#include "mozilla/ResultVariant.h"
1415

@@ -42,6 +43,33 @@ size_t compute_normalized_len(std::string_view src) {
4243
return len;
4344
}
4445

46+
std::optional<size_t> compute_unencoded_normalized_len(JSContext *cx, JS::HandleString value) {
47+
auto linear = JS_EnsureLinearString(cx, value);
48+
if (!linear) {
49+
return std::nullopt;
50+
}
51+
auto len = JS::GetDeflatedUTF8StringLength(linear);
52+
size_t two_byte_length = JS::GetLinearStringLength(linear);
53+
for (size_t i = 0; i < two_byte_length; i++) {
54+
char16_t ch = JS::GetLinearStringCharAt(linear, i);
55+
56+
if (ch == CR) {
57+
if (i+1 < two_byte_length) {
58+
char16_t next = JS::GetLinearStringCharAt(linear, i+1);
59+
if (next == LF) {
60+
i += 1;
61+
// the character is already accounted for
62+
continue;
63+
}
64+
}
65+
len += 1;
66+
} else if (ch == LF) {
67+
len += 1; // CRLF
68+
}
69+
}
70+
return len;
71+
}
72+
4573
// Normalizes newlines in a string by replacing:
4674
// - CR not followed by LF -> CRLF
4775
// - LF not preceded by CR -> CRLF
@@ -517,12 +545,15 @@ mozilla::Result<size_t, OutOfMemory> MultipartFormDataImpl::query_length(JSConte
517545
total += 2 * crlf_len;
518546

519547
RootedValue value_str(cx, entry.value);
520-
auto value = core::encode(cx, value_str);
548+
JS::RootedString value(cx, JS::ToString(cx, value_str));
521549
if (!value) {
522550
return mozilla::Result<size_t, OutOfMemory>(OutOfMemory {});
523551
}
524-
525-
total += compute_normalized_len(value);
552+
auto value_len = compute_unencoded_normalized_len(cx, value);
553+
if (!value_len.has_value()) {
554+
return mozilla::Result<size_t, OutOfMemory>(OutOfMemory {});
555+
}
556+
total += value_len.value();
526557
} else {
527558
MOZ_ASSERT(File::is_instance(entry.value));
528559
RootedObject obj(cx, &entry.value.toObject());

0 commit comments

Comments
 (0)