Browse Source

fix: broken `chrome.scripting` compilation (#39725)

fix: broken chrome.scripting impl after roll
Shelley Vohr 1 year ago
parent
commit
54d8402a6c

+ 159 - 224
shell/browser/extensions/api/scripting/scripting_api.cc

@@ -51,9 +51,7 @@ constexpr char kDuplicateFileSpecifiedError[] =
     "Duplicate file specified: '*'.";
 constexpr char kExactlyOneOfCssAndFilesError[] =
     "Exactly one of 'css' and 'files' must be specified.";
-constexpr char kFilesExceededSizeLimitError[] =
-    "Scripts could not be loaded because '*' exceeds the maximum script size "
-    "or the extension's maximum total script size.";
+constexpr char kNonExistentScriptIdError[] = "Nonexistent script ID '*'";
 
 // Note: CSS always injects as soon as possible, so we default to
 // document_start. Because of tab loading, there's no guarantee this will
@@ -61,45 +59,6 @@ constexpr char kFilesExceededSizeLimitError[] =
 constexpr mojom::RunLocation kCSSRunLocation =
     mojom::RunLocation::kDocumentStart;
 
-// Returns if the extension provided `script_id` (without an internal UserScript
-// prefix) is valid and populates `error` if invalid.
-bool IsScriptIDValid(const std::string& script_id, std::string* error) {
-  if (script_id.empty()) {
-    *error = "Script's ID must not be empty";
-    return false;
-  }
-
-  if (script_id[0] == UserScript::kReservedScriptIDPrefix) {
-    *error = base::StringPrintf("Script's ID '%s' must not start with '%c'",
-                                script_id.c_str(),
-                                UserScript::kReservedScriptIDPrefix);
-    return false;
-  }
-
-  return true;
-}
-
-// Iterates over `scripts` and adds a prefix to each script's id to indicate
-// that the script is a dynamic content script. Returns false and populates
-// `error` if any extension provided id in `scripts` is invalid. While this
-// might result in only some of the ids in `scripts` being modified, this should
-// have no effect on API calls as the API method handler will return with
-// `error`.
-bool AddDynamicScriptPrefixToScriptIDs(
-    std::vector<api::scripting::RegisteredContentScript>& scripts,
-    std::string* error) {
-  CHECK(error);
-  for (auto& script : scripts) {
-    if (!IsScriptIDValid(script.id, error)) {
-      return false;
-    }
-
-    script.id = scripting::CreateDynamicScriptID(script.id);
-  }
-
-  return true;
-}
-
 // Converts the given `style_origin` to a CSSOrigin.
 mojom::CSSOrigin ConvertStyleOriginToCSSOrigin(
     api::scripting::StyleOrigin style_origin) {
@@ -537,37 +496,12 @@ std::unique_ptr<UserScript> ParseUserScript(
   return result;
 }
 
-ValidateContentScriptsResult ValidateParsedScriptsOnFileThread(
-    ExtensionResource::SymlinkPolicy symlink_policy,
-    std::unique_ptr<UserScriptList> scripts) {
-  DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
-
-  // Validate that claimed script resources actually exist, and are UTF-8
-  // encoded.
-  std::string error;
-  std::vector<InstallWarning> warnings;
-  bool are_script_files_valid = script_parsing::ValidateFileSources(
-      *scripts, symlink_policy, &error, &warnings);
-
-  // Script files over the per script/extension limit are recorded as warnings.
-  // However, for the scripting API we should treat "install warnings" as
-  // errors by turning this call into a no-op and returning an error.
-  if (!warnings.empty() && error.empty()) {
-    error = ErrorUtils::FormatErrorMessage(kFilesExceededSizeLimitError,
-                                           warnings[0].specific);
-    are_script_files_valid = false;
-  }
-
-  return std::make_pair(std::move(scripts), are_script_files_valid
-                                                ? absl::nullopt
-                                                : absl::make_optional(error));
-}
-
 // Converts a UserScript object to a api::scripting::RegisteredContentScript
 // object, used for getRegisteredContentScripts.
 api::scripting::RegisteredContentScript CreateRegisteredContentScriptInfo(
     const UserScript& script) {
   api::scripting::RegisteredContentScript script_info;
+  CHECK_EQ(UserScript::Source::kDynamicContentScript, script.GetSource());
   script_info.id = script.id();
 
   script_info.matches.emplace();
@@ -965,18 +899,23 @@ ScriptingRegisterContentScriptsFunction::
 ScriptingRegisterContentScriptsFunction::
     ~ScriptingRegisterContentScriptsFunction() = default;
 
-ExtensionFunction::ResponseAction
-ScriptingRegisterContentScriptsFunction::Run() {
-  absl::optional<api::scripting::RegisterContentScripts::Params> params =
-      api::scripting::RegisterContentScripts::Params::Create(args());
+ExtensionFunction::ResponseAction ScriptingUpdateContentScriptsFunction::Run() {
+  absl::optional<api::scripting::UpdateContentScripts::Params> params =
+      api::scripting::UpdateContentScripts::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params);
 
   std::vector<api::scripting::RegisteredContentScript>& scripts =
       params->scripts;
   std::string error;
+
   // Add the prefix for dynamic content scripts onto the IDs of all scripts in
   // `scripts` before continuing.
-  if (!AddDynamicScriptPrefixToScriptIDs(scripts, &error)) {
+  std::set<std::string> ids_to_update = scripting::CreateDynamicScriptIds(
+      scripts, UserScript::Source::kDynamicContentScript,
+      std::set<std::string>(), &error);
+
+  if (!error.empty()) {
+    CHECK(ids_to_update.empty());
     return RespondNow(Error(std::move(error)));
   }
 
@@ -984,64 +923,100 @@ ScriptingRegisterContentScriptsFunction::Run() {
       ExtensionSystem::Get(browser_context())
           ->user_script_manager()
           ->GetUserScriptLoaderForExtension(extension()->id());
-  std::set<std::string> existing_script_ids = loader->GetDynamicScriptIDs();
-  std::set<std::string> new_script_ids;
 
-  for (const auto& script : scripts) {
-    if (base::Contains(existing_script_ids, script.id) ||
-        base::Contains(new_script_ids, script.id)) {
-      std::string error_script_id =
-          UserScript::TrimPrefixFromScriptID(script.id);
-      return RespondNow(Error(base::StringPrintf("Duplicate script ID '%s'",
-                                                 error_script_id.c_str())));
+  std::map<std::string, api::scripting::RegisteredContentScript>
+      loaded_scripts_metadata;
+  const UserScriptList& dynamic_scripts = loader->GetLoadedDynamicScripts();
+  for (const std::unique_ptr<UserScript>& script : dynamic_scripts) {
+    if (script->GetSource() == UserScript::Source::kDynamicContentScript) {
+      loaded_scripts_metadata.emplace(
+          script->id(), CreateRegisteredContentScriptInfo(*script));
     }
+  }
 
-    new_script_ids.insert(script.id);
+  for (const auto& script : scripts) {
+    std::string error_script_id = UserScript::TrimPrefixFromScriptID(script.id);
+    if (loaded_scripts_metadata.find(script.id) ==
+        loaded_scripts_metadata.end()) {
+      return RespondNow(
+          Error(base::StringPrintf("Script with ID '%s' does not exist "
+                                   "or is not fully registered",
+                                   error_script_id.c_str())));
+    }
   }
 
   std::u16string parse_error;
   auto parsed_scripts = std::make_unique<UserScriptList>();
-  std::set<std::string> persistent_script_ids;
   const int valid_schemes = UserScript::ValidUserScriptSchemes(
       scripting::kScriptsCanExecuteEverywhere);
 
+  std::set<std::string> updated_script_ids_to_persist;
+  std::set<std::string> persistent_script_ids =
+      loader->GetPersistentDynamicScriptIDs();
+
   parsed_scripts->reserve(scripts.size());
   for (size_t i = 0; i < scripts.size(); ++i) {
-    if (!scripts[i].matches) {
-      std::string error_script_id =
-          UserScript::TrimPrefixFromScriptID(scripts[i].id);
-      return RespondNow(
-          Error(base::StringPrintf("Script with ID '%s' must specify 'matches'",
-                                   error_script_id.c_str())));
+    api::scripting::RegisteredContentScript& update_delta = scripts[i];
+    DCHECK(base::Contains(loaded_scripts_metadata, update_delta.id));
+
+    api::scripting::RegisteredContentScript& updated_script =
+        loaded_scripts_metadata[update_delta.id];
+
+    if (update_delta.matches)
+      updated_script.matches = std::move(update_delta.matches);
+
+    if (update_delta.exclude_matches)
+      updated_script.exclude_matches = std::move(update_delta.exclude_matches);
+
+    if (update_delta.js)
+      updated_script.js = std::move(update_delta.js);
+
+    if (update_delta.css)
+      updated_script.css = std::move(update_delta.css);
+
+    if (update_delta.all_frames)
+      *updated_script.all_frames = *update_delta.all_frames;
+
+    if (update_delta.match_origin_as_fallback) {
+      *updated_script.match_origin_as_fallback =
+          *update_delta.match_origin_as_fallback;
+    }
+
+    if (update_delta.run_at != api::extension_types::RunAt::kNone) {
+      updated_script.run_at = update_delta.run_at;
     }
 
     // Parse/Create user script.
     std::unique_ptr<UserScript> user_script =
-        ParseUserScript(browser_context(), *extension(), scripts[i], i,
+        ParseUserScript(browser_context(), *extension(), updated_script, i,
                         valid_schemes, &parse_error);
     if (!user_script)
       return RespondNow(Error(base::UTF16ToASCII(parse_error)));
 
-    // Scripts will persist across sessions by default.
-    if (!scripts[i].persist_across_sessions ||
-        *scripts[i].persist_across_sessions) {
-      persistent_script_ids.insert(user_script->id());
+    // Persist the updated script if the flag is specified as true, or if the
+    // original script is persisted and the flag is not specified.
+    if ((update_delta.persist_across_sessions &&
+         *update_delta.persist_across_sessions) ||
+        (!update_delta.persist_across_sessions &&
+         base::Contains(persistent_script_ids, update_delta.id))) {
+      updated_script_ids_to_persist.insert(update_delta.id);
     }
+
     parsed_scripts->push_back(std::move(user_script));
   }
 
   // Add new script IDs now in case another call with the same script IDs is
   // made immediately following this one.
-  loader->AddPendingDynamicScriptIDs(std::move(new_script_ids));
+  loader->AddPendingDynamicScriptIDs(std::move(ids_to_update));
 
   GetExtensionFileTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&ValidateParsedScriptsOnFileThread,
+      base::BindOnce(&scripting::ValidateParsedScriptsOnFileThread,
                      script_parsing::GetSymlinkPolicy(extension()),
                      std::move(parsed_scripts)),
-      base::BindOnce(&ScriptingRegisterContentScriptsFunction::
-                         OnContentScriptFilesValidated,
-                     this, std::move(persistent_script_ids)));
+      base::BindOnce(
+          &ScriptingUpdateContentScriptsFunction::OnContentScriptFilesValidated,
+          this, std::move(updated_script_ids_to_persist)));
 
   // Balanced in `OnContentScriptFilesValidated()` or
   // `OnContentScriptsRegistered()`.
@@ -1051,10 +1026,11 @@ ScriptingRegisterContentScriptsFunction::Run() {
 
 void ScriptingRegisterContentScriptsFunction::OnContentScriptFilesValidated(
     std::set<std::string> persistent_script_ids,
-    ValidateContentScriptsResult result) {
+    scripting::ValidateScriptsResult result) {
   // We cannot proceed if the `browser_context` is not valid as the
   // `ExtensionSystem` will not exist.
   if (!browser_context()) {
+    Release();  // Matches the `AddRef()` in `Run()`.
     return;
   }
 
@@ -1067,8 +1043,9 @@ void ScriptingRegisterContentScriptsFunction::OnContentScriptFilesValidated(
 
   if (error.has_value()) {
     std::set<std::string> ids_to_remove;
-    for (const auto& script : *scripts)
+    for (const auto& script : *scripts) {
       ids_to_remove.insert(script->id());
+    }
 
     loader->RemovePendingDynamicScriptIDs(std::move(ids_to_remove));
     Respond(Error(std::move(*error)));
@@ -1108,7 +1085,8 @@ ScriptingGetRegisteredContentScriptsFunction::Run() {
   std::set<std::string> id_filter;
   if (filter && filter->ids) {
     for (const std::string& id : *(filter->ids)) {
-      id_filter.insert(scripting::CreateDynamicScriptID(id));
+      id_filter.insert(scripting::AddPrefixToDynamicScriptId(
+          id, UserScript::Source::kDynamicContentScript));
     }
   }
 
@@ -1122,16 +1100,19 @@ ScriptingGetRegisteredContentScriptsFunction::Run() {
   std::set<std::string> persistent_script_ids =
       loader->GetPersistentDynamicScriptIDs();
   for (const std::unique_ptr<UserScript>& script : dynamic_scripts) {
-    if (id_filter.empty() || base::Contains(id_filter, script->id())) {
-      auto registered_script = CreateRegisteredContentScriptInfo(*script);
-      registered_script.persist_across_sessions =
-          base::Contains(persistent_script_ids, script->id());
-
-      // Remove the internally used prefix from the `script`'s ID before
-      // returning.
-      registered_script.id = script->GetIDWithoutPrefix();
-      script_infos.push_back(std::move(registered_script));
+    if (script->GetSource() != UserScript::Source::kDynamicContentScript) {
+      continue;
+    }
+    if (!id_filter.empty() && !base::Contains(id_filter, script->id())) {
+      continue;
     }
+    auto registered_script = CreateRegisteredContentScriptInfo(*script);
+    registered_script.persist_across_sessions =
+        base::Contains(persistent_script_ids, script->id());
+    // Remove the internally used prefix from the `script`'s ID before
+    // returning.
+    registered_script.id = script->GetIDWithoutPrefix();
+    script_infos.push_back(std::move(registered_script));
   }
 
   return RespondNow(
@@ -1151,48 +1132,50 @@ ScriptingUnregisterContentScriptsFunction::Run() {
   EXTENSION_FUNCTION_VALIDATE(params);
 
   absl::optional<api::scripting::ContentScriptFilter>& filter = params->filter;
-  std::set<std::string> ids_to_remove;
-
   ExtensionUserScriptLoader* loader =
       ExtensionSystem::Get(browser_context())
           ->user_script_manager()
           ->GetUserScriptLoaderForExtension(extension()->id());
-  std::set<std::string> existing_script_ids = loader->GetDynamicScriptIDs();
-  if (filter && filter->ids) {
-    for (const auto& provided_id : *filter->ids) {
-      std::string error;
-      if (!IsScriptIDValid(provided_id, &error)) {
-        return RespondNow(Error(std::move(error)));
-      }
-
-      // Add the dynamic content script prefix to `provided_id` before checking
-      // against `existing_script_ids`.
-      std::string id_with_prefix =
-          scripting::CreateDynamicScriptID(provided_id);
-      if (!base::Contains(existing_script_ids, id_with_prefix)) {
-        return RespondNow(Error(base::StringPrintf("Nonexistent script ID '%s'",
-                                                   provided_id.c_str())));
-      }
-
-      ids_to_remove.insert(id_with_prefix);
-    }
-  }
 
   // TODO(crbug.com/1300657): Only clear all scripts if `filter` did not specify
   // the list of scripts ids to remove.
-  if (ids_to_remove.empty()) {
+  if (!filter || !filter->ids || filter->ids->empty()) {
     loader->ClearDynamicScripts(
+        UserScript::Source::kDynamicContentScript,
         base::BindOnce(&ScriptingUnregisterContentScriptsFunction::
                            OnContentScriptsUnregistered,
                        this));
-  } else {
-    loader->RemoveDynamicScripts(
-        std::move(ids_to_remove),
-        base::BindOnce(&ScriptingUnregisterContentScriptsFunction::
-                           OnContentScriptsUnregistered,
-                       this));
+    return RespondLater();
+  }
+
+  std::set<std::string> ids_to_remove;
+  std::set<std::string> existing_script_ids =
+      loader->GetDynamicScriptIDs(UserScript::Source::kDynamicContentScript);
+
+  std::string error;
+  for (const auto& provided_id : *filter->ids) {
+    if (!scripting::IsScriptIdValid(provided_id, &error)) {
+      return RespondNow(Error(std::move(error)));
+    }
+
+    // Add the dynamic content script prefix to `provided_id` before checking
+    // against `existing_script_ids`.
+    std::string id_with_prefix = scripting::AddPrefixToDynamicScriptId(
+        provided_id, UserScript::Source::kDynamicContentScript);
+    if (!base::Contains(existing_script_ids, id_with_prefix)) {
+      return RespondNow(Error(ErrorUtils::FormatErrorMessage(
+          kNonExistentScriptIdError, provided_id.c_str())));
+    }
+
+    ids_to_remove.insert(id_with_prefix);
   }
 
+  loader->RemoveDynamicScripts(
+      std::move(ids_to_remove),
+      base::BindOnce(&ScriptingUnregisterContentScriptsFunction::
+                         OnContentScriptsUnregistered,
+                     this));
+
   return RespondLater();
 }
 
@@ -1209,124 +1192,75 @@ ScriptingUpdateContentScriptsFunction::ScriptingUpdateContentScriptsFunction() =
 ScriptingUpdateContentScriptsFunction::
     ~ScriptingUpdateContentScriptsFunction() = default;
 
-ExtensionFunction::ResponseAction ScriptingUpdateContentScriptsFunction::Run() {
-  absl::optional<api::scripting::UpdateContentScripts::Params> params =
-      api::scripting::UpdateContentScripts::Params::Create(args());
+ExtensionFunction::ResponseAction
+ScriptingRegisterContentScriptsFunction::Run() {
+  absl::optional<api::scripting::RegisterContentScripts::Params> params =
+      api::scripting::RegisterContentScripts::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params);
 
   std::vector<api::scripting::RegisteredContentScript>& scripts =
       params->scripts;
-  std::string error;
-  // Add the prefix for dynamic content scripts onto the IDs of all scripts in
-  // `scripts` before continuing.
-  if (!AddDynamicScriptPrefixToScriptIDs(scripts, &error)) {
-    return RespondNow(Error(std::move(error)));
-  }
-
   ExtensionUserScriptLoader* loader =
       ExtensionSystem::Get(browser_context())
           ->user_script_manager()
           ->GetUserScriptLoaderForExtension(extension()->id());
 
-  std::map<std::string, api::scripting::RegisteredContentScript>
-      loaded_scripts_metadata;
-  const UserScriptList& dynamic_scripts = loader->GetLoadedDynamicScripts();
-  for (const std::unique_ptr<UserScript>& script : dynamic_scripts) {
-    loaded_scripts_metadata.emplace(script->id(),
-                                    CreateRegisteredContentScriptInfo(*script));
-  }
-
-  std::set<std::string> ids_to_update;
-  for (const auto& script : scripts) {
-    std::string error_script_id = UserScript::TrimPrefixFromScriptID(script.id);
-    if (loaded_scripts_metadata.find(script.id) ==
-        loaded_scripts_metadata.end()) {
-      return RespondNow(
-          Error(base::StringPrintf("Script with ID '%s' does not exist "
-                                   "or is not fully registered",
-                                   error_script_id.c_str())));
-    }
-
-    if (base::Contains(ids_to_update, script.id)) {
-      return RespondNow(Error(base::StringPrintf("Duplicate script ID '%s'",
-                                                 error_script_id.c_str())));
-    }
-
-    ids_to_update.insert(script.id);
+  // Create script ids for dynamic content scripts.
+  std::string error;
+  std::set<std::string> existing_script_ids =
+      loader->GetDynamicScriptIDs(UserScript::Source::kDynamicContentScript);
+  std::set<std::string> new_script_ids = scripting::CreateDynamicScriptIds(
+      scripts, UserScript::Source::kDynamicContentScript, existing_script_ids,
+      &error);
+
+  if (!error.empty()) {
+    CHECK(new_script_ids.empty());
+    return RespondNow(Error(std::move(error)));
   }
 
+  // Parse content scripts.
   std::u16string parse_error;
   auto parsed_scripts = std::make_unique<UserScriptList>();
+  std::set<std::string> persistent_script_ids;
   const int valid_schemes = UserScript::ValidUserScriptSchemes(
       scripting::kScriptsCanExecuteEverywhere);
 
-  std::set<std::string> updated_script_ids_to_persist;
-  std::set<std::string> persistent_script_ids =
-      loader->GetPersistentDynamicScriptIDs();
-
   parsed_scripts->reserve(scripts.size());
   for (size_t i = 0; i < scripts.size(); ++i) {
-    api::scripting::RegisteredContentScript& update_delta = scripts[i];
-    DCHECK(base::Contains(loaded_scripts_metadata, update_delta.id));
-
-    api::scripting::RegisteredContentScript& updated_script =
-        loaded_scripts_metadata[update_delta.id];
-
-    if (update_delta.matches)
-      updated_script.matches = std::move(update_delta.matches);
-
-    if (update_delta.exclude_matches)
-      updated_script.exclude_matches = std::move(update_delta.exclude_matches);
-
-    if (update_delta.js)
-      updated_script.js = std::move(update_delta.js);
-
-    if (update_delta.css)
-      updated_script.css = std::move(update_delta.css);
-
-    if (update_delta.all_frames)
-      *updated_script.all_frames = *update_delta.all_frames;
-
-    if (update_delta.match_origin_as_fallback) {
-      *updated_script.match_origin_as_fallback =
-          *update_delta.match_origin_as_fallback;
-    }
-
-    if (update_delta.run_at != api::extension_types::RunAt::kNone) {
-      updated_script.run_at = update_delta.run_at;
+    if (!scripts[i].matches) {
+      std::string error_script_id =
+          UserScript::TrimPrefixFromScriptID(scripts[i].id);
+      return RespondNow(
+          Error(base::StringPrintf("Script with ID '%s' must specify 'matches'",
+                                   error_script_id.c_str())));
     }
 
-    // Parse/Create user script.
     std::unique_ptr<UserScript> user_script =
-        ParseUserScript(browser_context(), *extension(), updated_script, i,
+        ParseUserScript(browser_context(), *extension(), scripts[i], i,
                         valid_schemes, &parse_error);
     if (!user_script)
       return RespondNow(Error(base::UTF16ToASCII(parse_error)));
 
-    // Persist the updated script if the flag is specified as true, or if the
-    // original script is persisted and the flag is not specified.
-    if ((update_delta.persist_across_sessions &&
-         *update_delta.persist_across_sessions) ||
-        (!update_delta.persist_across_sessions &&
-         base::Contains(persistent_script_ids, update_delta.id))) {
-      updated_script_ids_to_persist.insert(update_delta.id);
+    // Scripts will persist across sessions by default.
+    if (!scripts[i].persist_across_sessions ||
+        *scripts[i].persist_across_sessions) {
+      persistent_script_ids.insert(user_script->id());
     }
-
     parsed_scripts->push_back(std::move(user_script));
   }
 
   // Add new script IDs now in case another call with the same script IDs is
   // made immediately following this one.
-  loader->AddPendingDynamicScriptIDs(std::move(ids_to_update));
+  loader->AddPendingDynamicScriptIDs(std::move(new_script_ids));
 
   GetExtensionFileTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE,
-      base::BindOnce(&ValidateParsedScriptsOnFileThread,
+      base::BindOnce(&scripting::ValidateParsedScriptsOnFileThread,
                      script_parsing::GetSymlinkPolicy(extension()),
                      std::move(parsed_scripts)),
-      base::BindOnce(
-          &ScriptingUpdateContentScriptsFunction::OnContentScriptFilesValidated,
-          this, std::move(updated_script_ids_to_persist)));
+      base::BindOnce(&ScriptingRegisterContentScriptsFunction::
+                         OnContentScriptFilesValidated,
+                     this, std::move(persistent_script_ids)));
 
   // Balanced in `OnContentScriptFilesValidated()` or
   // `OnContentScriptsRegistered()`.
@@ -1336,10 +1270,11 @@ ExtensionFunction::ResponseAction ScriptingUpdateContentScriptsFunction::Run() {
 
 void ScriptingUpdateContentScriptsFunction::OnContentScriptFilesValidated(
     std::set<std::string> persistent_script_ids,
-    ValidateContentScriptsResult result) {
+    scripting::ValidateScriptsResult result) {
   // We cannot proceed if the `browser_context` is not valid as the
   // `ExtensionSystem` will not exist.
   if (!browser_context()) {
+    Release();  // Matches the `AddRef()` in `Run()`.
     return;
   }
 

+ 3 - 5
shell/browser/extensions/api/scripting/scripting_api.h

@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "chrome/common/extensions/api/scripting.h"
+#include "extensions/browser/api/scripting/scripting_utils.h"
 #include "extensions/browser/extension_function.h"
 #include "extensions/browser/script_executor.h"
 #include "extensions/common/mojom/code_injection.mojom.h"
@@ -108,9 +109,6 @@ class ScriptingRemoveCSSFunction : public ExtensionFunction {
   void OnCSSRemoved(std::vector<ScriptExecutor::FrameResult> results);
 };
 
-using ValidateContentScriptsResult =
-    std::pair<std::unique_ptr<UserScriptList>, absl::optional<std::string>>;
-
 class ScriptingRegisterContentScriptsFunction : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("scripting.registerContentScripts",
@@ -131,7 +129,7 @@ class ScriptingRegisterContentScriptsFunction : public ExtensionFunction {
   // Called when script files have been checked.
   void OnContentScriptFilesValidated(
       std::set<std::string> persistent_script_ids,
-      ValidateContentScriptsResult result);
+      scripting::ValidateScriptsResult result);
 
   // Called when content scripts have been registered.
   void OnContentScriptsRegistered(const absl::optional<std::string>& error);
@@ -196,7 +194,7 @@ class ScriptingUpdateContentScriptsFunction : public ExtensionFunction {
   // Called when script files have been checked.
   void OnContentScriptFilesValidated(
       std::set<std::string> persistent_script_ids,
-      ValidateContentScriptsResult result);
+      scripting::ValidateScriptsResult result);
 
   // Called when content scripts have been updated.
   void OnContentScriptsUpdated(const absl::optional<std::string>& error);