[RESTRICT AUTOMERGE] Fix Integer Overflow in libpac

From the upstream patch
(https://chromium.googlesource.com/v8/v8.git/+/7b27040e66c8a83006aebc90fe97d21bb42156a7%5E%21/#F0):

"""
Harden JSFunction::CalculateInstanceSizeHelper(...)
"""

Bug: 117556220

Test: /data/local/nativetest/proxy_resolver_v8_unittest/proxy_resolver_v8_unittest

Test: gts-tradefed run gts --test \
  com.google.android.gts.devicepolicy.DeviceOwnerTest#testProxyPacProxyTest \
  --module GtsGmscoreHostTestCases

Test: PoC from bug report

Merged-In: I2e02d994f107e64e4f465b4d8a02d4159a95240e
Merged-In: I72321236f4d4cf8da993addc3ef7a1dc018c434b

Change-Id: I72321236f4d4cf8da993addc3ef7a1dc018c434b
diff --git a/src/objects.cc b/src/objects.cc
index e711a21..7a180ba 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -13103,6 +13103,46 @@
   map->StartInobjectSlackTracking();
 }
 
+namespace {
+bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
+                              Handle<JSFunction> constructor,
+                              Handle<Map> constructor_initial_map) {
+    // Create a new map with the size and number of in-object properties
+    // suggested by |function|.
+
+    // Link initial map and constructor function if the new.target is actually a
+    // subclass constructor.
+    if (!IsSubclassConstructor(new_target->shared()->kind())) {
+        return false;
+    }
+
+    Handle<Object> prototype(new_target->instance_prototype(), isolate);
+    InstanceType instance_type = constructor_initial_map->instance_type();
+    DCHECK(CanSubclassHaveInobjectProperties(instance_type));
+    int internal_fields =
+        JSObject::GetInternalFieldCount(*constructor_initial_map);
+    int pre_allocated = constructor_initial_map->GetInObjectProperties() -
+                        constructor_initial_map->unused_property_fields();
+    int instance_size;
+    int in_object_properties;
+    new_target->CalculateInstanceSizeForDerivedClass(
+        instance_type, internal_fields, &instance_size,
+        &in_object_properties);
+
+    int unused_property_fields = in_object_properties - pre_allocated;
+    Handle<Map> map =
+        Map::CopyInitialMap(constructor_initial_map, instance_size,
+                            in_object_properties, unused_property_fields);
+    map->set_new_target_is_base(false);
+
+    JSFunction::SetInitialMap(new_target, map, prototype);
+    map->SetConstructor(*constructor);
+    map->set_construction_counter(Map::kNoSlackTracking);
+    map->StartInobjectSlackTracking();
+    return true;
+}
+
+}  // namespace
 
 // static
 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
@@ -13121,42 +13161,10 @@
 
     // Check that |function|'s initial map still in sync with the |constructor|,
     // otherwise we must create a new initial map for |function|.
-    if (function->has_initial_map() &&
-        function->initial_map()->GetConstructor() == *constructor) {
+    if (FastInitializeDerivedMap(isolate, function, constructor,
+                                 constructor_initial_map)) {
       return handle(function->initial_map(), isolate);
     }
-
-    // Create a new map with the size and number of in-object properties
-    // suggested by |function|.
-
-    // Link initial map and constructor function if the new.target is actually a
-    // subclass constructor.
-    if (IsSubclassConstructor(function->shared()->kind())) {
-      Handle<Object> prototype(function->instance_prototype(), isolate);
-      InstanceType instance_type = constructor_initial_map->instance_type();
-      DCHECK(CanSubclassHaveInobjectProperties(instance_type));
-      int internal_fields =
-          JSObject::GetInternalFieldCount(*constructor_initial_map);
-      int pre_allocated = constructor_initial_map->GetInObjectProperties() -
-                          constructor_initial_map->unused_property_fields();
-      int instance_size;
-      int in_object_properties;
-      function->CalculateInstanceSizeForDerivedClass(
-          instance_type, internal_fields, &instance_size,
-          &in_object_properties);
-
-      int unused_property_fields = in_object_properties - pre_allocated;
-      Handle<Map> map =
-          Map::CopyInitialMap(constructor_initial_map, instance_size,
-                              in_object_properties, unused_property_fields);
-      map->set_new_target_is_base(false);
-
-      JSFunction::SetInitialMap(function, map, prototype);
-      map->SetConstructor(*constructor);
-      map->set_construction_counter(Map::kNoSlackTracking);
-      map->StartInobjectSlackTracking();
-      return map;
-    }
   }
 
   // Slow path, new.target is either a proxy or can't cache the map.
@@ -13756,15 +13764,17 @@
                                              int* instance_size,
                                              int* in_object_properties) {
   int header_size = JSObject::GetHeaderSize(instance_type);
-  DCHECK_LE(requested_internal_fields,
-            (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
+  int max_nof_fields =
+      (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2;
+  CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
+  *in_object_properties = Min(requested_in_object_properties, max_nof_fields);
+  CHECK_LE(requested_internal_fields, max_nof_fields - *in_object_properties);
   *instance_size =
-      Min(header_size +
-              ((requested_internal_fields + requested_in_object_properties)
-               << kPointerSizeLog2),
-          JSObject::kMaxInstanceSize);
-  *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
-                          requested_internal_fields;
+      header_size +
+      ((requested_internal_fields + *in_object_properties) << kPointerSizeLog2);
+  CHECK_EQ(*in_object_properties,
+           ((*instance_size - header_size) >> kPointerSizeLog2) -
+               requested_internal_fields);
 }
 
 
@@ -13789,7 +13799,13 @@
     if (!current->IsJSFunction()) break;
     JSFunction* func = JSFunction::cast(current);
     SharedFunctionInfo* shared = func->shared();
-    expected_nof_properties += shared->expected_nof_properties();
+    int count = shared->expected_nof_properties();
+    // Check that the estimate is sane.
+    if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
+      expected_nof_properties += count;
+    } else {
+      expected_nof_properties = JSObject::kMaxInObjectProperties;
+    }
     if (!IsSubclassConstructor(shared->kind())) {
       break;
     }
diff --git a/src/objects.h b/src/objects.h
index 747a4f0..67c233f 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2649,6 +2649,9 @@
   static const int kHeaderSize = kElementsOffset + kPointerSize;
 
   STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
+  static const int kMaxInObjectProperties =
+      (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
+  STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
 
   typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;