|
14 | 14 | #include "mozilla/ResultVariant.h" |
15 | 15 |
|
16 | 16 | #include <fmt/format.h> |
| 17 | +#include <optional> |
17 | 18 | #include <string> |
18 | 19 |
|
19 | 20 | namespace { |
@@ -48,24 +49,41 @@ std::optional<size_t> compute_unencoded_normalized_len(JSContext *cx, JS::Handle |
48 | 49 | if (!linear) { |
49 | 50 | return std::nullopt; |
50 | 51 | } |
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; |
| 52 | + auto extra_bytes_needed = [](const auto *chars, const auto len) { |
| 53 | + size_t extra = 0; |
| 54 | + for (size_t i = 0; i < len; i++) { |
| 55 | + auto ch = chars[i]; |
| 56 | + if (ch == CR) { |
| 57 | + if (i+1 < len) { |
| 58 | + char16_t next = chars[i+1]; |
| 59 | + if (next == LF) { |
| 60 | + i += 1; |
| 61 | + // the character is already accounted for |
| 62 | + continue; |
| 63 | + } |
63 | 64 | } |
| 65 | + extra += 1; |
| 66 | + } else if (ch == LF) { |
| 67 | + extra += 1; |
64 | 68 | } |
65 | | - len += 1; |
66 | | - } else if (ch == LF) { |
67 | | - len += 1; // CRLF |
68 | 69 | } |
| 70 | + return extra; |
| 71 | + }; |
| 72 | + auto len = JS::GetDeflatedUTF8StringLength(linear); |
| 73 | + size_t chars_len = JS::GetLinearStringLength(linear); |
| 74 | + JS::AutoCheckCannotGC nogc; |
| 75 | + if (JS::LinearStringHasLatin1Chars(linear)) { |
| 76 | + auto chars = JS::GetLatin1LinearStringChars(nogc, linear); |
| 77 | + if (!chars) { |
| 78 | + return std::nullopt; |
| 79 | + } |
| 80 | + len += extra_bytes_needed(chars, chars_len); |
| 81 | + } else { |
| 82 | + auto chars = JS::GetTwoByteLinearStringChars(nogc, linear); |
| 83 | + if (!chars) { |
| 84 | + return std::nullopt; |
| 85 | + } |
| 86 | + len += extra_bytes_needed(chars, chars_len); |
69 | 87 | } |
70 | 88 | return len; |
71 | 89 | } |
|
0 commit comments