Migrate to the new v8::String::Write* APIs

In https://crrev.com/c/5975682 we introduced new versions of the
v8::String::Write* APIs. This CL migrates the chromium uses of the old
APIs to the new ones.

Bug: 373485796, 376071292
Change-Id: I1905a9b65638c85580ea73b04edd8328f16fd683
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6018204
Reviewed-by: Daniel Cheng <[email protected]>
Commit-Queue: Samuel Groß <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1384241}
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc
index d8e6da65..bee5bb61 100644
--- a/components/translate/content/renderer/translate_agent.cc
+++ b/components/translate/content/renderer/translate_agent.cc
@@ -370,12 +370,13 @@
   }
 
   v8::Local<v8::String> v8_str = result.As<v8::String>();
-  int length = v8_str->Utf8Length(isolate);
-  if (length <= 0)
+  size_t length = v8_str->Utf8LengthV2(isolate);
+  if (length == 0) {
     return std::string();
+  }
 
-  std::string str(static_cast<size_t>(length), '\0');
-  v8_str->WriteUtf8(isolate, &str[0], length);
+  std::string str(length, '\0');
+  v8_str->WriteUtf8V2(isolate, str.data(), length);
   return str;
 }
 
diff --git a/gin/converter.cc b/gin/converter.cc
index 62209ca..04bfeb77 100644
--- a/gin/converter.cc
+++ b/gin/converter.cc
@@ -154,10 +154,9 @@
   if (!val->IsString())
     return false;
   Local<String> str = Local<String>::Cast(val);
-  int length = str->Utf8Length(isolate);
+  size_t length = str->Utf8LengthV2(isolate);
   out->resize(length);
-  str->WriteUtf8(isolate, &(*out)[0], length, NULL,
-                 String::NO_NULL_TERMINATION);
+  str->WriteUtf8V2(isolate, out->data(), length);
   return true;
 }
 
@@ -175,12 +174,11 @@
   if (!val->IsString())
     return false;
   Local<String> str = Local<String>::Cast(val);
-  int length = str->Length();
-  // Note that the reinterpret cast is because on Windows string16 is an alias
-  // to wstring, and hence has character type wchar_t not uint16_t.
-  str->Write(isolate,
-             reinterpret_cast<uint16_t*>(base::WriteInto(out, length + 1)), 0,
-             length);
+  uint32_t length = str->Length();
+  out->resize(length);
+  static_assert(sizeof(char16_t) == sizeof(uint16_t),
+                "char16_t isn't the same as uint16_t");
+  str->WriteV2(isolate, 0, length, reinterpret_cast<uint16_t*>(out->data()));
   return true;
 }
 
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_compile_hints_common.cc b/third_party/blink/renderer/bindings/core/v8/v8_compile_hints_common.cc
index 72b1e538..d3dd0009 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_compile_hints_common.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_compile_hints_common.cc
@@ -17,14 +17,13 @@
   if (!name_value->ToString(context).ToLocal(&name_string)) {
     return 0;
   }
-  int name_length = name_string->Utf8Length(isolate);
+  size_t name_length = name_string->Utf8LengthV2(isolate);
   if (name_length == 0) {
     return 0;
   }
 
-  std::string name_std_string(name_length + 1, '\0');
-  name_string->WriteUtf8(isolate, &name_std_string[0]);
-  name_std_string.resize(name_length);
+  std::string name_std_string(name_length, '\0');
+  name_string->WriteUtf8V2(isolate, name_std_string.data(), name_length);
 
   // We need the hash function to be stable across computers, thus using
   // PersistentHash.
diff --git a/third_party/blink/renderer/core/css/css_style_declaration.cc b/third_party/blink/renderer/core/css/css_style_declaration.cc
index cea0429..3cf16f3 100644
--- a/third_party/blink/renderer/core/css/css_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/css_style_declaration.cc
@@ -224,13 +224,12 @@
     // it or parse it in some other way. So if it's short enough, we try to
     // construct a simple StringView on our own.
     const v8::Local<v8::String> string = value.As<v8::String>();
-    if (string->Length() <= 128 && string->IsOneByte()) {
+    uint32_t length = string->Length();
+    if (length <= 128 && string->IsOneByte()) {
       LChar buffer[128];
-      int len =
-          string->WriteOneByte(script_state->GetIsolate(), buffer, /*start=*/0,
-                               /*length=*/-1, v8::String::NO_NULL_TERMINATION);
+      string->WriteOneByteV2(script_state->GetIsolate(), 0, length, buffer);
       SetPropertyInternal(
-          unresolved_property, String(), StringView(buffer, len), false,
+          unresolved_property, String(), StringView(buffer, length), false,
           execution_context->GetSecureContextMode(), exception_state);
       if (exception_state.HadException()) {
         return NamedPropertySetterResult::kIntercepted;
diff --git a/third_party/blink/renderer/modules/websockets/websocket_stream.cc b/third_party/blink/renderer/modules/websockets/websocket_stream.cc
index 8e79907..e61d4cd 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_stream.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_stream.cc
@@ -389,14 +389,12 @@
   }
   // Skip one string copy by using v8::String UTF8 conversion instead of going
   // via WTF::String.
-  int expected_length = string_chunk->Utf8Length(isolate) + 1;
-  std::string message(expected_length, '\0');
-  int written_length = string_chunk->WriteUtf8(
-      isolate, &message[0], -1, nullptr, v8::String::REPLACE_INVALID_UTF8);
-  DCHECK_EQ(expected_length, written_length);
-  DCHECK_GT(expected_length, 0);
-  DCHECK_EQ(message.back(), '\0');
-  message.pop_back();  // Remove the null terminator.
+  size_t utf8_length = string_chunk->Utf8LengthV2(isolate);
+  std::string message(utf8_length, '\0');
+  size_t written_length =
+      string_chunk->WriteUtf8V2(isolate, message.data(), utf8_length,
+                                v8::String::WriteFlags::kReplaceInvalidUtf8);
+  DCHECK_EQ(utf8_length, written_length);
   if (creator_->channel_->Send(message, std::move(callback)) ==
       WebSocketChannel::SendResult::kSentSynchronously) {
     is_writing_ = false;
diff --git a/third_party/blink/renderer/platform/bindings/to_blink_string.cc b/third_party/blink/renderer/platform/bindings/to_blink_string.cc
index 4a4bad5..d3604b928 100644
--- a/third_party/blink/renderer/platform/bindings/to_blink_string.cc
+++ b/third_party/blink/renderer/platform/bindings/to_blink_string.cc
@@ -18,7 +18,9 @@
   static const StringClass& FromStringResource(v8::Isolate* isolate,
                                                StringResourceBase*);
   template <typename V8StringTrait>
-  static StringClass FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
+  static StringClass FromV8String(v8::Isolate*,
+                                  v8::Local<v8::String>,
+                                  uint32_t);
 };
 
 template <>
@@ -28,7 +30,7 @@
     return resource->GetWTFString();
   }
   template <typename V8StringTrait>
-  static String FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
+  static String FromV8String(v8::Isolate*, v8::Local<v8::String>, uint32_t);
 };
 
 template <>
@@ -38,7 +40,9 @@
     return resource->GetAtomicString(isolate);
   }
   template <typename V8StringTrait>
-  static AtomicString FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
+  static AtomicString FromV8String(v8::Isolate*,
+                                   v8::Local<v8::String>,
+                                   uint32_t);
 };
 
 struct V8StringTwoBytesTrait {
@@ -46,8 +50,9 @@
   ALWAYS_INLINE static void Write(v8::Isolate* isolate,
                                   v8::Local<v8::String> v8_string,
                                   base::span<CharType> buffer) {
-    v8_string->Write(isolate, reinterpret_cast<uint16_t*>(buffer.data()), 0,
-                     static_cast<int>(buffer.size()));
+    DCHECK_LE(buffer.size(), static_cast<uint32_t>(v8_string->Length()));
+    v8_string->WriteV2(isolate, 0, buffer.size(),
+                       reinterpret_cast<uint16_t*>(buffer.data()));
   }
 };
 
@@ -56,16 +61,16 @@
   ALWAYS_INLINE static void Write(v8::Isolate* isolate,
                                   v8::Local<v8::String> v8_string,
                                   base::span<CharType> buffer) {
-    v8_string->WriteOneByte(isolate, buffer.data(), 0,
-                            static_cast<int>(buffer.size()));
+    DCHECK_LE(buffer.size(), static_cast<uint32_t>(v8_string->Length()));
+    v8_string->WriteOneByteV2(isolate, 0, buffer.size(), buffer.data());
   }
 };
 
 template <typename V8StringTrait>
 String StringTraits<String>::FromV8String(v8::Isolate* isolate,
                                           v8::Local<v8::String> v8_string,
-                                          int length) {
-  DCHECK(v8_string->Length() == length);
+                                          uint32_t length) {
+  DCHECK_EQ(static_cast<uint32_t>(v8_string->Length()), length);
   base::span<typename V8StringTrait::CharType> buffer;
   String result = String::CreateUninitialized(length, buffer);
   V8StringTrait::Write(isolate, v8_string, buffer);
@@ -76,15 +81,15 @@
 AtomicString StringTraits<AtomicString>::FromV8String(
     v8::Isolate* isolate,
     v8::Local<v8::String> v8_string,
-    int length) {
-  DCHECK(v8_string->Length() == length);
+    uint32_t length) {
+  DCHECK_EQ(static_cast<uint32_t>(v8_string->Length()), length);
   static const int kInlineBufferSize =
       32 / sizeof(typename V8StringTrait::CharType);
   if (length <= kInlineBufferSize) {
     typename V8StringTrait::CharType inline_buffer[kInlineBufferSize];
     base::span<typename V8StringTrait::CharType> buffer_span(inline_buffer);
-    V8StringTrait::Write(isolate, v8_string, buffer_span);
-    return AtomicString(buffer_span.first(static_cast<size_t>(length)));
+    V8StringTrait::Write(isolate, v8_string, buffer_span.first(length));
+    return AtomicString(buffer_span.first(length));
   }
   base::span<typename V8StringTrait::CharType> buffer;
   String string = String::CreateUninitialized(length, buffer);
@@ -153,7 +158,7 @@
                             bool can_externalize,
                             bool is_one_byte,
                             bool* was_externalized) {
-  int length = v8_string->Length();
+  uint32_t length = v8_string->Length();
   StringType result =
       is_one_byte ? StringTraits<StringType>::template FromV8String<
                         V8StringOneByteTrait>(isolate, v8_string, length)
@@ -206,7 +211,7 @@
                                                         string_resource);
   }
 
-  int length = v8_string->Length();
+  uint32_t length = v8_string->Length();
   if (!length) [[unlikely]] {
     return StringType(g_empty_atom);
   }
@@ -247,7 +252,7 @@
         .Impl();
   }
 
-  int length = v8_string->Length();
+  uint32_t length = v8_string->Length();
   if (!length) [[unlikely]] {
     return StringView(g_empty_atom);
   }
@@ -324,16 +329,14 @@
   // behavior.
   if (is_one_byte) {
     LChar* lchar = backing_store.Realloc<LChar>(length);
-    v8_string->WriteOneByte(isolate, lchar, 0, length);
+    v8_string->WriteOneByteV2(isolate, 0, length, lchar);
     return StringView(lchar, length);
   }
 
   UChar* uchar = backing_store.Realloc<UChar>(length);
   static_assert(sizeof(UChar) == sizeof(uint16_t),
                 "UChar isn't the same as uint16_t");
-  // reinterpret_cast is needed on windows as UChar is a wchar_t and not
-  // an int64_t.
-  v8_string->Write(isolate, reinterpret_cast<uint16_t*>(uchar), 0, length);
+  v8_string->WriteV2(isolate, 0, length, reinterpret_cast<uint16_t*>(uchar));
   return StringView(uchar, length);
 }