diff options
20 files changed, 545 insertions, 535 deletions
diff --git a/components/nacl.gyp b/components/nacl.gyp index 23d886e..2c70b7d 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp @@ -159,6 +159,8 @@ 'nacl/renderer/manifest_downloader.h', 'nacl/renderer/manifest_service_channel.cc', 'nacl/renderer/manifest_service_channel.h', + 'nacl/renderer/json_manifest.cc', + 'nacl/renderer/json_manifest.h', 'nacl/renderer/nexe_load_manager.cc', 'nacl/renderer/nexe_load_manager.h', 'nacl/renderer/pnacl_translation_resource_host.cc', @@ -175,6 +177,7 @@ ], 'dependencies': [ '../content/content.gyp:content_renderer', + '../third_party/jsoncpp/jsoncpp.gyp:jsoncpp', '../third_party/WebKit/public/blink.gyp:blink', '../webkit/common/webkit_common.gyp:webkit_common', ], diff --git a/components/nacl/renderer/DEPS b/components/nacl/renderer/DEPS index e4fd874..d7b9c93 100644 --- a/components/nacl/renderer/DEPS +++ b/components/nacl/renderer/DEPS @@ -11,6 +11,7 @@ include_rules = [ "+ppapi/thunk", "+v8/include", + "+third_party/jsoncpp/source/include/json", "+third_party/WebKit/public/platform", "+third_party/WebKit/public/web", ] diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/components/nacl/renderer/json_manifest.cc index 418339c..8459f1f 100644 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc +++ b/components/nacl/renderer/json_manifest.cc @@ -1,28 +1,19 @@ -/* - * Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <algorithm> - -#include "ppapi/native_client/src/trusted/plugin/json_manifest.h" - -#include <stdlib.h> - -#include "native_client/src/include/nacl_base.h" -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "native_client/src/include/portability.h" -#include "native_client/src/shared/platform/nacl_check.h" -#include "ppapi/c/private/ppb_nacl_private.h" -#include "ppapi/cpp/dev/url_util_dev.h" -#include "ppapi/cpp/var.h" -#include "ppapi/native_client/src/trusted/plugin/plugin_error.h" -#include "ppapi/native_client/src/trusted/plugin/utility.h" +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/nacl/renderer/json_manifest.h" + +#include <set> + +#include "base/logging.h" +#include "base/macros.h" +#include "components/nacl/renderer/nexe_load_manager.h" #include "third_party/jsoncpp/source/include/json/reader.h" +#include "third_party/jsoncpp/source/include/json/value.h" +#include "url/gurl.h" -namespace plugin { +namespace nacl { namespace { // Top-level section name keys @@ -97,13 +88,13 @@ const char* const kOptLevelKey = "optlevel"; // } // Returns the key for the architecture in non-SFI mode. -nacl::string GetNonSFIKey(const nacl::string& sandbox_isa) { +std::string GetNonSFIKey(const std::string& sandbox_isa) { return sandbox_isa + "-nonsfi"; } // Looks up |property_name| in the vector |valid_names| with length // |valid_name_count|. Returns true if |property_name| is found. -bool FindMatchingProperty(const nacl::string& property_name, +bool FindMatchingProperty(const std::string& property_name, const char** valid_names, size_t valid_name_count) { for (size_t i = 0; i < valid_name_count; ++i) { @@ -120,15 +111,15 @@ bool FindMatchingProperty(const nacl::string& property_name, // was the property value of |container_key|. // E.g., "container_key" : dictionary bool IsValidDictionary(const Json::Value& dictionary, - const nacl::string& container_key, - const nacl::string& parent_key, + const std::string& container_key, + const std::string& parent_key, const char** valid_keys, size_t valid_key_count, const char** required_keys, size_t required_key_count, - nacl::string* error_string) { + std::string* error_string) { if (!dictionary.isObject()) { - nacl::stringstream error_stream; + std::stringstream error_stream; error_stream << parent_key << " property '" << container_key << "' is non-dictionary value '" << dictionary.toStyledString() << "'."; @@ -138,21 +129,21 @@ bool IsValidDictionary(const Json::Value& dictionary, // Check for unknown dictionary members. Json::Value::Members members = dictionary.getMemberNames(); for (size_t i = 0; i < members.size(); ++i) { - nacl::string property_name = members[i]; + std::string property_name = members[i]; if (!FindMatchingProperty(property_name, valid_keys, valid_key_count)) { // For forward compatibility, we do not prohibit other keys being in // the dictionary. - PLUGIN_PRINTF(("WARNING: '%s' property '%s' has unknown key '%s'.\n", - parent_key.c_str(), - container_key.c_str(), property_name.c_str())); + VLOG(1) << "WARNING: '" << parent_key << "' property '" + << container_key << "' has unknown key '" + << property_name << "'."; } } // Check for required members. for (size_t i = 0; i < required_key_count; ++i) { if (!dictionary.isMember(required_keys[i])) { - nacl::stringstream error_stream; + std::stringstream error_stream; error_stream << parent_key << " property '" << container_key << "' does not have required key: '" << required_keys[i] << "'."; @@ -166,10 +157,10 @@ bool IsValidDictionary(const Json::Value& dictionary, // Validate a "url" dictionary assuming it was resolved from container_key. // E.g., "container_key" : { "url": "foo.txt" } bool IsValidUrlSpec(const Json::Value& url_spec, - const nacl::string& container_key, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, - nacl::string* error_string) { + const std::string& container_key, + const std::string& parent_key, + const std::string& sandbox_isa, + std::string* error_string) { static const char* kManifestUrlSpecRequired[] = { kUrlKey }; @@ -181,32 +172,32 @@ bool IsValidUrlSpec(const Json::Value& url_spec, kOptLevelKey, }; urlSpecPlusOptional = kPnaclUrlSpecPlusOptional; - urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kPnaclUrlSpecPlusOptional); + urlSpecPlusOptionalLength = arraysize(kPnaclUrlSpecPlusOptional); } else { // URL specifications must not contain "pnacl-translate" keys. // This prohibits NaCl clients from invoking PNaCl. if (url_spec.isMember(kPnaclTranslateKey)) { - nacl::stringstream error_stream; + std::stringstream error_stream; error_stream << "PNaCl-like NMF with application/x-nacl mimetype instead " << "of x-pnacl mimetype (has " << kPnaclTranslateKey << ")."; *error_string = error_stream.str(); return false; } urlSpecPlusOptional = kManifestUrlSpecRequired; - urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kManifestUrlSpecRequired); + urlSpecPlusOptionalLength = arraysize(kManifestUrlSpecRequired); } if (!IsValidDictionary(url_spec, container_key, parent_key, urlSpecPlusOptional, urlSpecPlusOptionalLength, kManifestUrlSpecRequired, - NACL_ARRAY_SIZE(kManifestUrlSpecRequired), + arraysize(kManifestUrlSpecRequired), error_string)) { return false; } // Verify the correct types of the fields if they exist. Json::Value url = url_spec[kUrlKey]; if (!url.isString()) { - nacl::stringstream error_stream; + std::stringstream error_stream; error_stream << parent_key << " property '" << container_key << "' has non-string value '" << url.toStyledString() << "' for key '" << kUrlKey << "'."; @@ -215,7 +206,7 @@ bool IsValidUrlSpec(const Json::Value& url_spec, } Json::Value opt_level = url_spec[kOptLevelKey]; if (!opt_level.empty() && !opt_level.isNumeric()) { - nacl::stringstream error_stream; + std::stringstream error_stream; error_stream << parent_key << " property '" << container_key << "' has non-numeric value '" << opt_level.toStyledString() << "' for key '" << kOptLevelKey << "'."; @@ -229,53 +220,47 @@ bool IsValidUrlSpec(const Json::Value& url_spec, // it was resolved from container_key. // E.g., "container_key" : { "pnacl-translate" : URLSpec } bool IsValidPnaclTranslateSpec(const Json::Value& pnacl_spec, - const nacl::string& container_key, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, - nacl::string* error_string) { + const std::string& container_key, + const std::string& parent_key, + const std::string& sandbox_isa, + std::string* error_string) { static const char* kManifestPnaclSpecValid[] = { kPnaclDebugKey, kPnaclTranslateKey }; - static const char* kManifestPnaclSpecRequired[] = { - kPnaclTranslateKey - }; + static const char* kManifestPnaclSpecRequired[] = { kPnaclTranslateKey }; if (!IsValidDictionary(pnacl_spec, container_key, parent_key, kManifestPnaclSpecValid, - NACL_ARRAY_SIZE(kManifestPnaclSpecValid), + arraysize(kManifestPnaclSpecValid), kManifestPnaclSpecRequired, - NACL_ARRAY_SIZE(kManifestPnaclSpecRequired), + arraysize(kManifestPnaclSpecRequired), error_string)) { return false; } Json::Value url_spec = pnacl_spec[kPnaclTranslateKey]; - if (!IsValidUrlSpec(url_spec, kPnaclTranslateKey, - container_key, sandbox_isa, error_string)) { - return false; - } - return true; + return IsValidUrlSpec(url_spec, kPnaclTranslateKey, + container_key, sandbox_isa, error_string); } // Validates that |dictionary| is a valid ISA dictionary. An ISA dictionary // is validated to have keys from within the set of recognized ISAs. Unknown -// ISAs are allowed, but ignored and warnings are produced. It is also validated +// ISAs are allowed, but ignored and warnings are produced. It is also +// validated // that it must have an entry to match the ISA specified in |sandbox_isa| or // have a fallback 'portable' entry if there is no match. Returns true if // |dictionary| is an ISA to URL map. Sets |error_info| to something // descriptive if it fails. bool IsValidISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, + const std::string& parent_key, + const std::string& sandbox_isa, bool must_find_matching_entry, bool nonsfi_enabled, - ErrorInfo* error_info) { - if (error_info == NULL) return false; - + JsonManifest::ErrorInfo* error_info) { // An ISA to URL dictionary has to be an object. if (!dictionary.isObject()) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + parent_key + - " property is not an ISA to URL dictionary"); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = std::string("manifest: ") + parent_key + + " property is not an ISA to URL dictionary"; return false; } // Build the set of reserved ISA dictionary keys. @@ -287,7 +272,7 @@ bool IsValidISADictionary(const Json::Value& dictionary, kPortableKey }; isaProperties = kPnaclManifestISAProperties; - isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); + isaPropertiesLength = arraysize(kPnaclManifestISAProperties); } else { // The known values for NaCl ISA dictionaries in the manifest. static const char* kNaClManifestISAProperties[] = { @@ -303,14 +288,14 @@ bool IsValidISADictionary(const Json::Value& dictionary, kPortableKey }; isaProperties = kNaClManifestISAProperties; - isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); + isaPropertiesLength = arraysize(kNaClManifestISAProperties); } // Check that entries in the dictionary are structurally correct. Json::Value::Members members = dictionary.getMemberNames(); for (size_t i = 0; i < members.size(); ++i) { - nacl::string property_name = members[i]; + std::string property_name = members[i]; Json::Value property_value = dictionary[property_name]; - nacl::string error_string; + std::string error_string; if (FindMatchingProperty(property_name, isaProperties, isaPropertiesLength)) { @@ -332,33 +317,30 @@ bool IsValidISADictionary(const Json::Value& dictionary, parent_key != kProgramKey && !IsValidUrlSpec(property_value, property_name, parent_key, sandbox_isa, &error_string))) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + error_string); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = "manifest: " + error_string; return false; } } else { // For forward compatibility, we do not prohibit other keys being in // the dictionary, as they may be architectures supported in later // versions. However, the value of these entries must be an URLSpec. - PLUGIN_PRINTF(("IsValidISADictionary: unrecognized key '%s'.\n", - property_name.c_str())); + VLOG(1) << "IsValidISADictionary: unrecognized key '" + << property_name << "'."; if (!IsValidUrlSpec(property_value, property_name, parent_key, sandbox_isa, &error_string)) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + error_string); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = "manifest: " + error_string; return false; } } } if (sandbox_isa == kPortableKey) { - bool has_portable = dictionary.isMember(kPortableKey); - - if (!has_portable) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, - nacl::string("manifest: no version of ") + parent_key + - " given for portable."); + if (!dictionary.isMember(kPortableKey)) { + error_info->error = PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH; + error_info->string = "manifest: no version of " + parent_key + + " given for portable."; return false; } } else if (must_find_matching_entry) { @@ -370,46 +352,50 @@ bool IsValidISADictionary(const Json::Value& dictionary, bool has_portable = dictionary.isMember(kPortableKey); if (!has_isa && !has_nonsfi_isa && !has_portable) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, - nacl::string("manifest: no version of ") + parent_key + - " given for current arch and no portable version found."); + error_info->error = PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH; + error_info->string = "manifest: no version of " + parent_key + + " given for current arch and no portable version found."; return false; } } - return true; } -void GrabUrlAndPNaClOptions(const Json::Value& url_spec, - nacl::string* url, +void GrabUrlAndPnaclOptions(const Json::Value& url_spec, + std::string* url, PP_PNaClOptions* pnacl_options) { *url = url_spec[kUrlKey].asString(); pnacl_options->translate = PP_TRUE; if (url_spec.isMember(kOptLevelKey)) { int32_t opt_raw = url_spec[kOptLevelKey].asInt(); - int32_t opt_level; // Currently only allow 0 or 2, since that is what we test. if (opt_raw <= 0) - opt_level = 0; + pnacl_options->opt_level = 0; else - opt_level = 2; - pnacl_options->opt_level = opt_level; + pnacl_options->opt_level = 2; } } } // namespace -bool JsonManifest::Init(const nacl::string& manifest_json, +JsonManifest::JsonManifest(const std::string& manifest_base_url, + const std::string& sandbox_isa, + bool nonsfi_enabled, + bool pnacl_debug) + : manifest_base_url_(manifest_base_url), + sandbox_isa_(sandbox_isa), + nonsfi_enabled_(nonsfi_enabled), + pnacl_debug_(pnacl_debug) { } + +bool JsonManifest::Init(const std::string& manifest_json, ErrorInfo* error_info) { - if (error_info == NULL) { - return false; - } + CHECK(error_info); + Json::Reader reader; if (!reader.parse(manifest_json, dictionary_)) { - std::string json_error = reader.getFormatedErrorMessages(); - error_info->SetReport(PP_NACL_ERROR_MANIFEST_PARSING, - "manifest JSON parsing failed: " + json_error); + std::string json_error = reader.getFormattedErrorMessages(); + error_info->error = PP_NACL_ERROR_MANIFEST_PARSING; + error_info->string = "manifest JSON parsing failed: " + json_error; return false; } // Parse has ensured the string was valid JSON. Check that it matches the @@ -417,15 +403,86 @@ bool JsonManifest::Init(const nacl::string& manifest_json, return MatchesSchema(error_info); } -bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { - pp::Var exception; - if (error_info == NULL) { +bool JsonManifest::GetProgramURL(std::string* full_url, + PP_PNaClOptions* pnacl_options, + bool* uses_nonsfi_mode, + ErrorInfo* error_info) const { + if (!full_url) + return false; + CHECK(pnacl_options); + CHECK(uses_nonsfi_mode); + CHECK(error_info); + + const Json::Value& program = dictionary_[kProgramKey]; + std::string nexe_url; + if (!GetURLFromISADictionary(program, + kProgramKey, + &nexe_url, + pnacl_options, + uses_nonsfi_mode, + error_info)) { return false; } + + // The contents of the manifest are resolved relative to the manifest URL. + GURL base_gurl(manifest_base_url_); + if (!base_gurl.is_valid()) + return false; + + GURL resolved_gurl = base_gurl.Resolve(nexe_url); + if (!resolved_gurl.is_valid()) { + error_info->error = PP_NACL_ERROR_MANIFEST_RESOLVE_URL; + error_info->string = + "could not resolve url '" + nexe_url + + "' relative to manifest base url '" + manifest_base_url_.c_str() + + "'."; + return false; + } + *full_url = resolved_gurl.possibly_invalid_spec(); + return true; +} + +bool JsonManifest::ResolveKey(const std::string& key, + std::string* full_url, + PP_PNaClOptions* pnacl_options) const { + // key must be one of kProgramKey or kFileKey '/' file-section-key + if (full_url == NULL || pnacl_options == NULL) + return false; + + if (key == kProgramKey) + return GetKeyUrl(dictionary_, key, full_url, pnacl_options); + + std::string::const_iterator p = find(key.begin(), key.end(), '/'); + if (p == key.end()) { + VLOG(1) << "ResolveKey failed: invalid key, no slash: " << key; + return false; + } + + // generalize to permit other sections? + std::string prefix(key.begin(), p); + if (prefix != kFilesKey) { + VLOG(1) << "ResolveKey failed: invalid key, no \"files\" prefix: " << key; + return false; + } + + const Json::Value& files = dictionary_[kFilesKey]; + if (!files.isObject()) { + VLOG(1) << "ResolveKey failed: no \"files\" dictionary"; + return false; + } + + std::string rest(p + 1, key.end()); + if (!files.isMember(rest)) { + VLOG(1) << "ResolveKey failed: no such \"files\" entry: " << key; + return false; + } + return GetKeyUrl(files, rest, full_url, pnacl_options); +} + +bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { if (!dictionary_.isObject()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - "manifest: is not a json dictionary."); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = "manifest: is not a json dictionary."; return false; } Json::Value::Members members = dictionary_.getMemberNames(); @@ -434,20 +491,20 @@ bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { static const char* kManifestTopLevelProperties[] = { kProgramKey, kInterpreterKey, kFilesKey }; - nacl::string property_name = members[i]; + std::string property_name = members[i]; if (!FindMatchingProperty(property_name, kManifestTopLevelProperties, - NACL_ARRAY_SIZE(kManifestTopLevelProperties))) { - PLUGIN_PRINTF(("JsonManifest::MatchesSchema: WARNING: unknown top-level " - "section '%s' in manifest.\n", property_name.c_str())); + arraysize(kManifestTopLevelProperties))) { + VLOG(1) << "JsonManifest::MatchesSchema: WARNING: unknown top-level " + << "section '" << property_name << "' in manifest."; } } // A manifest file must have a program section. if (!dictionary_.isMember(kProgramKey)) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: missing '") + kProgramKey + "' section."); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = std::string("manifest: missing '") + kProgramKey + + "' section."; return false; } @@ -479,18 +536,18 @@ bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { // Validate the file dictionary (if given). // The "files" key does not require a matching (portable or sandbox_isa_) - // entry at schema validation time for NaCl. This allows manifests to specify - // resources that are only loaded for a particular sandbox_isa. + // entry at schema validation time for NaCl. This allows manifests to + // specify resources that are only loaded for a particular sandbox_isa. if (dictionary_.isMember(kFilesKey)) { const Json::Value& files = dictionary_[kFilesKey]; if (!files.isObject()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); + error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE; + error_info->string = std::string("manifest: '") + kFilesKey + + "' is not a dictionary."; } Json::Value::Members members = files.getMemberNames(); for (size_t i = 0; i < members.size(); ++i) { - nacl::string file_name = members[i]; + std::string file_name = members[i]; if (!IsValidISADictionary(files[file_name], file_name, sandbox_isa_, @@ -501,26 +558,54 @@ bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { } } } + return true; +} + +bool JsonManifest::GetKeyUrl(const Json::Value& dictionary, + const std::string& key, + std::string* full_url, + PP_PNaClOptions* pnacl_options) const { + DCHECK(full_url && pnacl_options); + if (!dictionary.isMember(key)) { + VLOG(1) << "GetKeyUrl failed: file " << key << " not found in manifest."; + return false; + } + const Json::Value& isa_dict = dictionary[key]; + std::string relative_url; + bool uses_nonsfi_mode; + ErrorInfo ignored_error_info; + if (!GetURLFromISADictionary(isa_dict, key, &relative_url, + pnacl_options, &uses_nonsfi_mode, + &ignored_error_info)) + return false; + // The contents of the manifest are resolved relative to the manifest URL. + GURL base_gurl(manifest_base_url_); + if (!base_gurl.is_valid()) + return false; + GURL resolved_gurl = base_gurl.Resolve(relative_url); + if (!resolved_gurl.is_valid()) + return false; + *full_url = resolved_gurl.possibly_invalid_spec(); return true; } bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - nacl::string* url, + const std::string& parent_key, + std::string* url, PP_PNaClOptions* pnacl_options, bool* uses_nonsfi_mode, ErrorInfo* error_info) const { - DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); + DCHECK(url && pnacl_options && error_info); // When the application actually requests a resolved URL, we must have // a matching entry (sandbox_isa_ or portable) for NaCl. ErrorInfo ignored_error_info; if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, nonsfi_enabled_, &ignored_error_info)) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, - "architecture " + sandbox_isa_ + - " is not found for file " + parent_key); + error_info->error = PP_NACL_ERROR_MANIFEST_RESOLVE_URL; + error_info->string = "architecture " + sandbox_isa_ + + " is not found for file " + parent_key; return false; } @@ -528,11 +613,11 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, // sandbox_isa_, its nonsfi mode, or kPortableKey is present in the // dictionary. *uses_nonsfi_mode = false; - nacl::string chosen_isa; + std::string chosen_isa; if (sandbox_isa_ == kPortableKey) { chosen_isa = kPortableKey; } else { - nacl::string nonsfi_isa = GetNonSFIKey(sandbox_isa_); + std::string nonsfi_isa = GetNonSFIKey(sandbox_isa_); if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) { chosen_isa = nonsfi_isa; *uses_nonsfi_mode = true; @@ -544,6 +629,7 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, // Should not reach here, because the earlier IsValidISADictionary() // call checked that the manifest covers the current architecture. DCHECK(false); + return false; } } @@ -552,10 +638,10 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, // If found, mark that it is a debug URL. Otherwise, fall back to // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL. if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) { - GrabUrlAndPNaClOptions(isa_spec[kPnaclDebugKey], url, pnacl_options); + GrabUrlAndPnaclOptions(isa_spec[kPnaclDebugKey], url, pnacl_options); pnacl_options->is_debug = PP_TRUE; } else if (isa_spec.isMember(kPnaclTranslateKey)) { - GrabUrlAndPNaClOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); + GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); } else { // NaCl *url = isa_spec[kUrlKey].asString(); @@ -565,110 +651,4 @@ bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, return true; } -bool JsonManifest::GetKeyUrl(const Json::Value& dictionary, - const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - DCHECK(full_url != NULL && pnacl_options != NULL); - if (!dictionary.isMember(key)) { - PLUGIN_PRINTF(("file key not found in manifest")); - return false; - } - const Json::Value& isa_dict = dictionary[key]; - nacl::string relative_url; - bool uses_nonsfi_mode; - - // We ignore the error_info we receive here but it's needed for the calls - // below. - ErrorInfo error_info; - - if (!GetURLFromISADictionary(isa_dict, key, &relative_url, - pnacl_options, &uses_nonsfi_mode, &error_info)) { - return false; - } - return ResolveURL(relative_url, full_url, &error_info); -} - -bool JsonManifest::GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const { - if (full_url == NULL || pnacl_options == NULL || error_info == NULL) - return false; - - const Json::Value& program = dictionary_[kProgramKey]; - nacl::string nexe_url; - if (!GetURLFromISADictionary(program, - kProgramKey, - &nexe_url, - pnacl_options, - uses_nonsfi_mode, - error_info)) { - return false; - } - return ResolveURL(nexe_url, full_url, error_info); -} - -bool JsonManifest::ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str()); - // key must be one of kProgramKey or kFileKey '/' file-section-key - - if (full_url == NULL || pnacl_options == NULL) - return false; - - if (key == kProgramKey) - return GetKeyUrl(dictionary_, key, full_url, pnacl_options); - nacl::string::const_iterator p = find(key.begin(), key.end(), '/'); - if (p == key.end()) { - std::string err = "ResolveKey: invalid key, no slash: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - - // generalize to permit other sections? - nacl::string prefix(key.begin(), p); - if (prefix != kFilesKey) { - std::string err = "ResolveKey: invalid key: no \"files\" prefix: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - - nacl::string rest(p + 1, key.end()); - - const Json::Value& files = dictionary_[kFilesKey]; - if (!files.isObject()) { - std::string err = "ResolveKey: no \"files\" dictionary"; - PLUGIN_PRINTF((err.c_str())); - return false; - } - if (!files.isMember(rest)) { - std::string err = "ResolveKey: no such \"files\" entry: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - return GetKeyUrl(files, rest, full_url, pnacl_options); -} - -bool JsonManifest::ResolveURL(const nacl::string& relative_url, - nacl::string* full_url, - ErrorInfo* error_info) const { - // The contents of the manifest are resolved relative to the manifest URL. - CHECK(url_util_ != NULL); - pp::Var resolved_url = - url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), - relative_url); - if (!resolved_url.is_string()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_RESOLVE_URL, - "could not resolve url '" + relative_url + - "' relative to manifest base url '" + manifest_base_url_.c_str() + - "'."); - return false; - } - *full_url = resolved_url.AsString(); - return true; -} - -} // namespace plugin +} // namespace nacl diff --git a/components/nacl/renderer/json_manifest.h b/components/nacl/renderer/json_manifest.h new file mode 100644 index 0000000..d8885d3 --- /dev/null +++ b/components/nacl/renderer/json_manifest.h @@ -0,0 +1,73 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H +#define COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H + +#include <set> +#include <string> + +#include "ppapi/c/pp_array_output.h" +#include "ppapi/c/private/ppb_nacl_private.h" +#include "third_party/jsoncpp/source/include/json/value.h" + +namespace nacl { +class NexeLoadManager; + +class JsonManifest { + public: + struct ErrorInfo { + PP_NaClError error; + std::string string; + }; + + JsonManifest(const std::string& manifest_base_url, + const std::string& sandbox_isa, + bool nonsfi_enabled, + bool pnacl_debug); + + // Initialize the manifest object for use by later lookups. Returns + // true if the manifest parses correctly and matches the schema. + bool Init(const std::string& json_manifest, ErrorInfo* error_info); + + // Gets the full program URL for the current sandbox ISA from the + // manifest file. + bool GetProgramURL(std::string* full_url, + PP_PNaClOptions* pnacl_options, + bool* uses_nonsfi_mode, + ErrorInfo* error_info) const; + + // Resolves a key from the "files" section to a fully resolved URL, + // i.e., relative URL values are fully expanded relative to the + // manifest's URL (via ResolveURL). + // If there was an error, details are reported via error_info. + bool ResolveKey(const std::string& key, + std::string* full_url, + PP_PNaClOptions* pnacl_options) const; + + private: + bool MatchesSchema(ErrorInfo* error_info); + bool GetKeyUrl(const Json::Value& dictionary, + const std::string& key, + std::string* full_url, + PP_PNaClOptions* pnacl_options) const; + bool GetURLFromISADictionary(const Json::Value& dictionary, + const std::string& parent_key, + std::string* url, + PP_PNaClOptions* pnacl_options, + bool* uses_nonsfi_mode, + ErrorInfo* error_info) const; + + std::string manifest_base_url_; + std::string sandbox_isa_; + bool nonsfi_enabled_; + bool pnacl_debug_; + + // The dictionary of manifest information parsed in Init(). + Json::Value dictionary_; +}; + +} // namespace nacl + +#endif // COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc index a4020d9..92595ec 100644 --- a/components/nacl/renderer/ppb_nacl_private_impl.cc +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc @@ -16,6 +16,7 @@ #include "components/nacl/common/nacl_switches.h" #include "components/nacl/common/nacl_types.h" #include "components/nacl/renderer/histogram.h" +#include "components/nacl/renderer/json_manifest.h" #include "components/nacl/renderer/manifest_downloader.h" #include "components/nacl/renderer/manifest_service_channel.h" #include "components/nacl/renderer/nexe_load_manager.h" @@ -87,7 +88,20 @@ typedef base::ScopedPtrHashMap<PP_Instance, NexeLoadManager> base::LazyInstance<NexeLoadManagerMap> g_load_manager_map = LAZY_INSTANCE_INITIALIZER; -NexeLoadManager* GetNexeLoadManager(PP_Instance instance) { +typedef base::ScopedPtrHashMap<int32_t, nacl::JsonManifest> JsonManifestMap; + +base::LazyInstance<JsonManifestMap> g_manifest_map = + LAZY_INSTANCE_INITIALIZER; + +base::LazyInstance<int32_t> g_next_manifest_id = + LAZY_INSTANCE_INITIALIZER; + +// We have to define a method here since we can't use a static initializer. +int32_t GetPNaClManifestId() { + return std::numeric_limits<int32_t>::max(); +} + +nacl::NexeLoadManager* GetNexeLoadManager(PP_Instance instance) { NexeLoadManagerMap& map = g_load_manager_map.Get(); NexeLoadManagerMap::iterator iter = map.find(instance); if (iter != map.end()) @@ -991,6 +1005,111 @@ void DownloadManifestToBufferCompletion(PP_Instance instance, callback.func(callback.user_data, pp_error); } +int32_t CreatePNaClManifest(PP_Instance /* instance */) { + return GetPNaClManifestId(); +} + +int32_t CreateJsonManifest(PP_Instance instance, + const char* manifest_url, + const char* isa_type, + const char* manifest_data) { + int32_t manifest_id = g_next_manifest_id.Get(); + g_next_manifest_id.Get()++; + + scoped_ptr<nacl::JsonManifest> j( + new nacl::JsonManifest( + manifest_url, + isa_type, + PP_ToBool(IsNonSFIModeEnabled()), + PP_ToBool(NaClDebugEnabledForURL(manifest_url)))); + JsonManifest::ErrorInfo error_info; + if (j->Init(manifest_data, &error_info)) { + g_manifest_map.Get().add(manifest_id, j.Pass()); + return manifest_id; + } + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); + if (load_manager) + load_manager->ReportLoadError(error_info.error, error_info.string); + return -1; +} + +void DestroyManifest(PP_Instance /* instance */, + int32_t manifest_id) { + if (manifest_id == GetPNaClManifestId()) + return; + g_manifest_map.Get().erase(manifest_id); +} + +PP_Bool ManifestGetProgramURL(PP_Instance instance, + int32_t manifest_id, + PP_Var* pp_full_url, + PP_PNaClOptions* pnacl_options, + PP_Bool* pp_uses_nonsfi_mode) { + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); + if (manifest_id == GetPNaClManifestId()) { + if (load_manager) { + load_manager->ReportLoadError( + PP_NACL_ERROR_MANIFEST_GET_NEXE_URL, + "pnacl manifest does not contain a program."); + } + return PP_FALSE; + } + + JsonManifestMap::iterator it = g_manifest_map.Get().find(manifest_id); + if (it == g_manifest_map.Get().end()) + return PP_FALSE; + + bool uses_nonsfi_mode; + std::string full_url; + JsonManifest::ErrorInfo error_info; + if (it->second->GetProgramURL(&full_url, pnacl_options, &uses_nonsfi_mode, + &error_info)) { + *pp_full_url = ppapi::StringVar::StringToPPVar(full_url); + *pp_uses_nonsfi_mode = PP_FromBool(uses_nonsfi_mode); + return PP_TRUE; + } + + if (load_manager) + load_manager->ReportLoadError(error_info.error, error_info.string); + return PP_FALSE; +} + +PP_Bool ManifestResolveKey(PP_Instance instance, + int32_t manifest_id, + const char* key, + PP_Var* pp_full_url, + PP_PNaClOptions* pnacl_options) { + if (manifest_id == GetPNaClManifestId()) { + pnacl_options->translate = PP_FALSE; + // We can only resolve keys in the files/ namespace. + const std::string kFilesPrefix = "files/"; + std::string key_string(key); + if (key_string.find(kFilesPrefix) == std::string::npos) { + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); + if (load_manager) + load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, + "key did not start with files/"); + return PP_FALSE; + } + std::string key_basename = key_string.substr(kFilesPrefix.length()); + std::string pnacl_url = + std::string("chrome://pnacl-translator/") + GetSandboxArch() + "/" + + key_basename; + *pp_full_url = ppapi::StringVar::StringToPPVar(pnacl_url); + return PP_TRUE; + } + + JsonManifestMap::iterator it = g_manifest_map.Get().find(manifest_id); + if (it == g_manifest_map.Get().end()) + return PP_FALSE; + + std::string full_url; + bool ok = it->second->ResolveKey(key, &full_url, pnacl_options); + if (ok) + *pp_full_url = ppapi::StringVar::StringToPPVar(full_url); + return PP_FromBool(ok); +} + const PPB_NaCl_Private nacl_interface = { &LaunchSelLdr, &StartPpapiProxy, @@ -1030,7 +1149,12 @@ const PPB_NaCl_Private nacl_interface = { &GetManifestURLArgument, &IsPNaCl, &DevInterfacesEnabled, - &DownloadManifestToBuffer + &DownloadManifestToBuffer, + &CreatePNaClManifest, + &CreateJsonManifest, + &DestroyManifest, + &ManifestGetProgramURL, + &ManifestResolveKey }; } // namespace diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl index 04b6758..a1fcb45 100644 --- a/ppapi/api/private/ppb_nacl_private.idl +++ b/ppapi/api/private/ppb_nacl_private.idl @@ -411,4 +411,25 @@ interface PPB_NaCl_Private { void DownloadManifestToBuffer([in] PP_Instance instance, [out] PP_Var data, [in] PP_CompletionCallback callback); + + int32_t CreatePnaclManifest([in] PP_Instance instance); + int32_t CreateJsonManifest([in] PP_Instance instance, + [in] str_t manifest_base_url, + [in] str_t sandbox_isa, + [in] str_t manifest_data); + + void DestroyManifest([in] PP_Instance instance, + [in] int32_t manifest_id); + + PP_Bool GetManifestProgramURL([in] PP_Instance instance, + [in] int32_t manifest_id, + [out] PP_Var full_url, + [out] PP_PNaClOptions pnacl_options, + [out] PP_Bool uses_nonsfi_mode); + + PP_Bool ManifestResolveKey([in] PP_Instance instance, + [in] int32_t manifest_id, + [in] str_t key, + [out] PP_Var full_url, + [out] PP_PNaClOptions pnacl_options); }; diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h index 9ac540a..bc4a182 100644 --- a/ppapi/c/private/ppb_nacl_private.h +++ b/ppapi/c/private/ppb_nacl_private.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/ppb_nacl_private.idl modified Sat May 3 04:07:13 2014. */ +/* From private/ppb_nacl_private.idl modified Mon May 5 10:57:38 2014. */ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ @@ -407,6 +407,22 @@ struct PPB_NaCl_Private_1_0 { void (*DownloadManifestToBuffer)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback); + int32_t (*CreatePnaclManifest)(PP_Instance instance); + int32_t (*CreateJsonManifest)(PP_Instance instance, + const char* manifest_base_url, + const char* sandbox_isa, + const char* manifest_data); + void (*DestroyManifest)(PP_Instance instance, int32_t manifest_id); + PP_Bool (*GetManifestProgramURL)(PP_Instance instance, + int32_t manifest_id, + struct PP_Var* full_url, + struct PP_PNaClOptions* pnacl_options, + PP_Bool* uses_nonsfi_mode); + PP_Bool (*ManifestResolveKey)(PP_Instance instance, + int32_t manifest_id, + const char* key, + struct PP_Var* full_url, + struct PP_PNaClOptions* pnacl_options); }; typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private; diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h deleted file mode 100644 index cf02798..0000000 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -// Manifest processing for JSON manifests. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ - -#include <map> -#include <set> -#include <string> - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" -#include "third_party/jsoncpp/source/include/json/value.h" - -struct PP_PNaClOptions; - -namespace pp { -class URLUtil_Dev; -} // namespace pp - -namespace plugin { - -class ErrorInfo; - -class JsonManifest : public Manifest { - public: - JsonManifest(const pp::URLUtil_Dev* url_util, - const nacl::string& manifest_base_url, - const nacl::string& sandbox_isa, - bool nonsfi_enabled, - bool pnacl_debug) - : url_util_(url_util), - manifest_base_url_(manifest_base_url), - sandbox_isa_(sandbox_isa), - nonsfi_enabled_(nonsfi_enabled), - pnacl_debug_(pnacl_debug), - dictionary_(Json::nullValue) { } - virtual ~JsonManifest() { } - - // Initialize the manifest object for use by later lookups. The return - // value is true if the manifest parses correctly and matches the schema. - bool Init(const nacl::string& json, ErrorInfo* error_info); - - // Gets the full program URL for the current sandbox ISA from the - // manifest file. - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const; - - // Resolves a key from the "files" section to a fully resolved URL, - // i.e., relative URL values are fully expanded relative to the - // manifest's URL (via ResolveURL). - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const; - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(JsonManifest); - - // Resolves a URL relative to the manifest base URL - bool ResolveURL(const nacl::string& relative_url, - nacl::string* full_url, - ErrorInfo* error_info) const; - - // Checks that |dictionary_| is a valid manifest, according to the schema. - // Returns true on success, and sets |error_info| to a detailed message - // if not. - bool MatchesSchema(ErrorInfo* error_info); - - bool GetKeyUrl(const Json::Value& dictionary, - const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const; - - bool GetURLFromISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - nacl::string* url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const; - - const pp::URLUtil_Dev* url_util_; - nacl::string manifest_base_url_; - nacl::string sandbox_isa_; - bool nonsfi_enabled_; - bool pnacl_debug_; - - Json::Value dictionary_; -}; - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h deleted file mode 100644 index 6a74dd6..0000000 --- a/ppapi/native_client/src/trusted/plugin/manifest.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -// Manifest interface class. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ - -#include <map> -#include <set> -#include <string> - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "third_party/jsoncpp/source/include/json/value.h" - -struct PP_PNaClOptions; - -namespace pp { -class URLUtil_Dev; -} // namespace pp - -namespace plugin { - -class ErrorInfo; - -class Manifest { - public: - Manifest() { } - virtual ~Manifest() { } - - // A convention in the interfaces below regarding permit_extension_url: - // Some manifests (e.g., the pnacl coordinator manifest) need to access - // resources from an extension origin distinct from the plugin's origin - // (e.g., the pnacl coordinator needs to load llc, ld, and some libraries). - // This out-parameter is true if this manifest lookup confers access to - // a resource in the extension origin. - - // Gets the full program URL for the current sandbox ISA from the - // manifest file. Fills in |pnacl_options| if the program requires - // PNaCl translation. - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const = 0; - - // Resolves a key from the "files" section to a fully resolved URL, - // i.e., relative URL values are fully expanded relative to the - // manifest's URL. Fills in |pnacl_options| if - // the resolved key requires a pnacl translation step to obtain - // the final requested resource. - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const = 0; - - protected: - NACL_DISALLOW_COPY_AND_ASSIGN(Manifest); -}; - - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index 071e534..ce2d4ba 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -34,7 +34,6 @@ #include "ppapi/cpp/dev/url_util_dev.h" #include "ppapi/cpp/module.h" -#include "ppapi/native_client/src/trusted/plugin/json_manifest.h" #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" @@ -136,11 +135,11 @@ void Plugin::HistogramHTTPStatusCode(const std::string& name, int status) { bool Plugin::LoadNaClModuleFromBackgroundThread( nacl::DescWrapper* wrapper, NaClSubprocess* subprocess, - const Manifest* manifest, + int32_t manifest_id, const SelLdrStartParams& params) { CHECK(!pp::Module::Get()->core()->IsMainThread()); ServiceRuntime* service_runtime = - new ServiceRuntime(this, manifest, false, uses_nonsfi_mode_, + new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_, pp::BlockUntilComplete(), pp::BlockUntilComplete()); subprocess->set_service_runtime(service_runtime); PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " @@ -228,7 +227,7 @@ void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, enable_crash_throttling); ErrorInfo error_info; ServiceRuntime* service_runtime = - new ServiceRuntime(this, manifest_.get(), true, uses_nonsfi_mode, + new ServiceRuntime(this, manifest_id_, true, uses_nonsfi_mode, init_done_cb, crash_cb); main_subprocess_.set_service_runtime(service_runtime); PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", @@ -293,7 +292,7 @@ bool Plugin::LoadNaClModuleContinuationIntern() { NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, nacl::DescWrapper* wrapper, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info) { nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( new NaClSubprocess("helper module", NULL, NULL)); @@ -320,7 +319,7 @@ NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, false /* enable_exception_handling */, true /* enable_crash_throttling */); if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(), - manifest, params)) { + manifest_id, params)) { return NULL; } // We need not wait for the init_done callback. We can block @@ -370,6 +369,7 @@ Plugin::Plugin(PP_Instance pp_instance) wrapper_factory_(NULL), time_of_last_progress_event_(0), nexe_open_time_(-1), + manifest_id_(-1), nacl_interface_(NULL), uma_interface_(this) { PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" @@ -580,20 +580,19 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { if (!SetManifestObject(manifest_json)) return; - nacl::string program_url; + PP_Var pp_program_url; PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; - bool uses_nonsfi_mode; - ErrorInfo error_info; - if (manifest_->GetProgramURL( - &program_url, &pnacl_options, &uses_nonsfi_mode, &error_info)) { + PP_Bool uses_nonsfi_mode; + if (nacl_interface_->GetManifestProgramURL(pp_instance(), + manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { + std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString(); // TODO(teravest): Make ProcessNaClManifest take responsibility for more of // this function. nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str()); - uses_nonsfi_mode_ = uses_nonsfi_mode; + uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); if (pnacl_options.translate) { pp::CompletionCallback translate_callback = callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); - // Will always call the callback on success or failure. pnacl_coordinator_.reset( PnaclCoordinator::BitcodeToNative(this, program_url, @@ -619,8 +618,6 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { return; } } - // Failed to select the program and/or the translator. - ReportLoadError(error_info); } void Plugin::RequestNaClManifest(const nacl::string& url) { @@ -663,30 +660,22 @@ void Plugin::RequestNaClManifest(const nacl::string& url) { bool Plugin::SetManifestObject(const nacl::string& manifest_json) { PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n", manifest_json.c_str())); - ErrorInfo error_info; - // Determine whether lookups should use portable (i.e., pnacl versions) // rather than platform-specific files. bool is_pnacl = nacl_interface_->IsPNaCl(pp_instance()); - bool nonsfi_mode_enabled = - PP_ToBool(nacl_interface_->IsNonSFIModeEnabled()); pp::Var manifest_base_url = pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance())); std::string manifest_base_url_str = manifest_base_url.AsString(); - bool pnacl_debug = GetNaClInterface()->NaClDebugEnabledForURL( - manifest_base_url_str.c_str()); const char* sandbox_isa = nacl_interface_->GetSandboxArch(); - nacl::scoped_ptr<JsonManifest> json_manifest( - new JsonManifest(pp::URLUtil_Dev::Get(), - manifest_base_url_str, - (is_pnacl ? kPortableArch : sandbox_isa), - nonsfi_mode_enabled, - pnacl_debug)); - if (!json_manifest->Init(manifest_json, &error_info)) { - ReportLoadError(error_info); + + int32_t manifest_id = nacl_interface_->CreateJsonManifest( + pp_instance(), + manifest_base_url_str.c_str(), + is_pnacl ? kPortableArch : sandbox_isa, + manifest_json.c_str()); + if (manifest_id == -1) return false; - } - manifest_.reset(json_manifest.release()); + manifest_id_ = manifest_id; return true; } diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index d9de561..15e2d19 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -8,7 +8,6 @@ 'common_sources': [ 'file_downloader.cc', 'file_utils.cc', - 'json_manifest.cc', 'module_ppapi.cc', 'nacl_subprocess.cc', 'plugin.cc', diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index c573bd2..1978be7 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -111,7 +111,7 @@ class Plugin : public pp::Instance { // Returns NULL or the NaClSubprocess of the new helper NaCl module. NaClSubprocess* LoadHelperNaClModule(const nacl::string& helper_url, nacl::DescWrapper* wrapper, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info); enum LengthComputable { @@ -164,8 +164,6 @@ class Plugin : public pp::Instance { // document to request the URL using CORS even if this function returns false. bool DocumentCanRequest(const std::string& url); - Manifest const* manifest() const { return manifest_.get(); } - // set_exit_status may be called off the main thread. void set_exit_status(int exit_status); @@ -206,7 +204,7 @@ class Plugin : public pp::Instance { // This will fully initialize the |subprocess| if the load was successful. bool LoadNaClModuleFromBackgroundThread(nacl::DescWrapper* wrapper, NaClSubprocess* subprocess, - const Manifest* manifest, + int32_t manifest_id, const SelLdrStartParams& params); // Start sel_ldr from the main thread, given the start params. @@ -304,9 +302,6 @@ class Plugin : public pp::Instance { nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_; - // The manifest dictionary. Used for looking up resources to be loaded. - nacl::scoped_ptr<Manifest> manifest_; - // Keep track of the FileDownloaders created to fetch urls. std::set<FileDownloader*> url_downloaders_; // Keep track of file descriptors opened by StreamAsFile(). @@ -334,6 +329,7 @@ class Plugin : public pp::Instance { int64_t nexe_open_time_; PP_Var manifest_data_var_; + int32_t manifest_id_; const PPB_NaCl_Private* nacl_interface_; pp::UMAPrivate uma_interface_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 93d2220..626536a 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -16,7 +16,6 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_uma_private.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h" @@ -26,62 +25,6 @@ namespace plugin { ////////////////////////////////////////////////////////////////////// -// Pnacl-specific manifest support. -////////////////////////////////////////////////////////////////////// - -// The PNaCl linker gets file descriptors via the service runtime's -// reverse service lookup. The reverse service lookup requires a manifest. -// Normally, that manifest is an NMF containing mappings for shared libraries. -// Here, we provide a manifest that redirects to PNaCl component files -// that are part of Chrome. -class PnaclManifest : public Manifest { - public: - PnaclManifest(const nacl::string& sandbox_arch) - : sandbox_arch_(sandbox_arch) { } - - virtual ~PnaclManifest() { } - - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const { - // Does not contain program urls. - UNREFERENCED_PARAMETER(full_url); - UNREFERENCED_PARAMETER(pnacl_options); - UNREFERENCED_PARAMETER(uses_nonsfi_mode); - UNREFERENCED_PARAMETER(error_info); - PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); - error_info->SetReport(PP_NACL_ERROR_MANIFEST_GET_NEXE_URL, - "pnacl manifest does not contain a program."); - return false; - } - - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - // All of the component files are native (do not require pnacl translate). - pnacl_options->translate = PP_FALSE; - // We can only resolve keys in the files/ namespace. - const nacl::string kFilesPrefix = "files/"; - size_t files_prefix_pos = key.find(kFilesPrefix); - if (files_prefix_pos == nacl::string::npos) { - PLUGIN_PRINTF(("key did not start with files/")); - return false; - } - // Resolve the full URL to the file. Provide it with a platform-specific - // prefix. - nacl::string key_basename = key.substr(kFilesPrefix.length()); - *full_url = PnaclUrls::GetBaseUrl() + sandbox_arch_ + "/" + key_basename; - return true; - } - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(PnaclManifest); - - nacl::string sandbox_arch_; -}; - -////////////////////////////////////////////////////////////////////// // UMA stat helpers. ////////////////////////////////////////////////////////////////////// @@ -180,10 +123,10 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( new PnaclCoordinator(plugin, pexe_url, pnacl_options, translate_notify_callback); - coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); - PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, ", - reinterpret_cast<const void*>(coordinator->manifest_.get()))); + PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest_id=%d)\n", + coordinator->manifest_id_)); + coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); coordinator->split_module_count_ = std::min(4, std::max(1, cpus)); @@ -204,7 +147,8 @@ PnaclCoordinator::PnaclCoordinator( plugin_(plugin), translate_notify_callback_(translate_notify_callback), translation_finished_reported_(false), - manifest_(new PnaclManifest(plugin->nacl_interface()->GetSandboxArch())), + manifest_id_( + GetNaClInterface()->CreatePnaclManifest(plugin->pp_instance())), pexe_url_(pexe_url), pnacl_options_(pnacl_options), split_module_count_(1), @@ -668,7 +612,7 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) { CHECK(translate_thread_ != NULL); translate_thread_->RunTranslate(report_translate_finished, - manifest_.get(), + manifest_id_, &obj_files_, temp_nexe_file_.get(), invalid_desc_wrapper_.get(), diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 99d6e70..954bb09 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -27,7 +27,6 @@ struct PP_PNaClOptions; namespace plugin { -class Manifest; class Plugin; class PnaclCoordinator; class PnaclTranslateThread; @@ -204,7 +203,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // The manifest used by resource loading and ld + llc's reverse service // to look up objects and libraries. - nacl::scoped_ptr<const Manifest> manifest_; + int32_t manifest_id_; // An auxiliary class that manages downloaded resources (llc and ld nexes). nacl::scoped_ptr<PnaclResources> resources_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc index 160066b..747d147 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc @@ -9,7 +9,6 @@ #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/c/pp_errors.h" #include "ppapi/native_client/src/trusted/plugin/file_utils.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" #include "ppapi/native_client/src/trusted/plugin/utility.h" diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc index 10f01bb..947bf1c7 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -39,7 +39,7 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), ld_subprocess_active_(false), done_(false), compile_time_(0), - manifest_(NULL), + manifest_id_(0), obj_files_(NULL), nexe_file_(NULL), coordinator_error_info_(NULL), @@ -53,7 +53,7 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), void PnaclTranslateThread::RunTranslate( const pp::CompletionCallback& finish_callback, - const Manifest* manifest, + int32_t manifest_id, const std::vector<TempFile*>* obj_files, TempFile* nexe_file, nacl::DescWrapper* invalid_desc_wrapper, @@ -63,7 +63,7 @@ void PnaclTranslateThread::RunTranslate( PnaclCoordinator* coordinator, Plugin* plugin) { PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); - manifest_ = manifest; + manifest_id_ = manifest_id; obj_files_ = obj_files; nexe_file_ = nexe_file; invalid_desc_wrapper_ = invalid_desc_wrapper; @@ -129,7 +129,7 @@ void PnaclTranslateThread::PutBytes(std::vector<char>* bytes, NaClSubprocess* PnaclTranslateThread::StartSubprocess( const nacl::string& url_for_nexe, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info) { PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n", url_for_nexe.c_str())); @@ -140,8 +140,8 @@ NaClSubprocess* PnaclTranslateThread::StartSubprocess( // string gets silently dropped by GURL. nacl::string full_url = resources_->GetFullUrl( url_for_nexe, plugin_->nacl_interface()->GetSandboxArch()); - nacl::scoped_ptr<NaClSubprocess> subprocess( - plugin_->LoadHelperNaClModule(full_url, wrapper, manifest, error_info)); + nacl::scoped_ptr<NaClSubprocess> subprocess(plugin_->LoadHelperNaClModule( + full_url, wrapper, manifest_id, error_info)); if (subprocess.get() == NULL) { PLUGIN_PRINTF(( "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n")); @@ -173,7 +173,7 @@ void PnaclTranslateThread::DoTranslate() { nacl::MutexLocker ml(&subprocess_mu_); int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); llc_subprocess_.reset( - StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLlcUrl(), manifest_id_, &error_info)); if (llc_subprocess_ == NULL) { TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP, "Compile process could not be created: " + @@ -350,7 +350,7 @@ bool PnaclTranslateThread::RunLdSubprocess() { nacl::MutexLocker ml(&subprocess_mu_); int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); ld_subprocess_.reset( - StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLdUrl(), manifest_id_, &error_info)); if (ld_subprocess_ == NULL) { TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, "Link process could not be created: " + diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h index db1dbf0..84ce392 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h @@ -28,7 +28,6 @@ class DescWrapper; namespace plugin { -class Manifest; class NaClSubprocess; class Plugin; class PnaclCoordinator; @@ -43,7 +42,7 @@ class PnaclTranslateThread { // Start the translation process. It will continue to run and consume data // as it is passed in with PutBytes. void RunTranslate(const pp::CompletionCallback& finish_callback, - const Manifest* manifest, + int32_t manifest_id, const std::vector<TempFile*>* obj_files, TempFile* nexe_file, nacl::DescWrapper* invalid_desc_wrapper, @@ -69,7 +68,7 @@ class PnaclTranslateThread { private: // Starts an individual llc or ld subprocess used for translation. NaClSubprocess* StartSubprocess(const nacl::string& url, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info); // Helper thread entry point for translation. Takes a pointer to // PnaclTranslateThread and calls DoTranslate(). @@ -114,7 +113,7 @@ class PnaclTranslateThread { int64_t compile_time_; // Data about the translation files, owned by the coordinator - const Manifest* manifest_; + int32_t manifest_id_; const std::vector<TempFile*>* obj_files_; TempFile* nexe_file_; nacl::DescWrapper* invalid_desc_wrapper_; diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index d7c8683..c3a7f94 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -47,7 +47,6 @@ #include "ppapi/cpp/core.h" #include "ppapi/cpp/completion_callback.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" @@ -198,13 +197,13 @@ void OpenManifestEntryResource::MaybeRunCallback(int32_t pp_error) { PluginReverseInterface::PluginReverseInterface( nacl::WeakRefAnchor* anchor, Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, ServiceRuntime* service_runtime, pp::CompletionCallback init_done_cb, pp::CompletionCallback crash_cb) : anchor_(anchor), plugin_(plugin), - manifest_(manifest), + manifest_id_(manifest_id), service_runtime_(service_runtime), shutting_down_(false), init_done_cb_(init_done_cb), @@ -347,9 +346,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); - std::string mapped_url; + PP_Var pp_mapped_url; PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; - if (!manifest_->ResolveKey(p->url, &mapped_url, &pnacl_options)) { + if (!GetNaClInterface()->ManifestResolveKey(plugin_->pp_instance(), + manifest_id_, + p->url.c_str(), + &pp_mapped_url, + &pnacl_options)) { NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); // Failed, and error_info has the details on what happened. Wake // up requesting thread -- we are done. @@ -362,6 +365,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( p->MaybeRunCallback(PP_OK); return; } + nacl::string mapped_url = pp::Var(pp_mapped_url).AsString(); NaClLog(4, "OpenManifestEntry_MainThreadContinuation: " "ResolveKey: %s -> %s (pnacl_translate(%d))\n", @@ -560,7 +564,7 @@ void PluginReverseInterface::AddTempQuotaManagedFile( } ServiceRuntime::ServiceRuntime(Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, bool main_service_runtime, bool uses_nonsfi_mode, pp::CompletionCallback init_done_cb, @@ -571,7 +575,7 @@ ServiceRuntime::ServiceRuntime(Plugin* plugin, reverse_service_(NULL), anchor_(new nacl::WeakRefAnchor()), rev_interface_(new PluginReverseInterface(anchor_, plugin, - manifest, + manifest_id, this, init_done_cb, crash_cb)), exit_status_(-1), diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index ca12764..74dc68d 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -40,7 +40,6 @@ class FileIO; namespace plugin { class ErrorInfo; -class Manifest; class OpenManifestEntryAsyncCallback; class Plugin; class SrpcClient; @@ -147,7 +146,7 @@ class PluginReverseInterface: public nacl::ReverseInterface { public: PluginReverseInterface(nacl::WeakRefAnchor* anchor, Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, ServiceRuntime* service_runtime, pp::CompletionCallback init_done_cb, pp::CompletionCallback crash_cb); @@ -206,7 +205,7 @@ class PluginReverseInterface: public nacl::ReverseInterface { nacl::WeakRefAnchor* anchor_; // holds a ref Plugin* plugin_; // value may be copied, but should be used only in // main thread in WeakRef-protected callbacks. - const Manifest* manifest_; + int32_t manifest_id_; ServiceRuntime* service_runtime_; NaClMutex mu_; NaClCondVar cv_; @@ -223,7 +222,7 @@ class ServiceRuntime { // TODO(sehr): This class should also implement factory methods, using the // Start method below. ServiceRuntime(Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, bool main_service_runtime, bool uses_nonsfi_mode, pp::CompletionCallback init_done_cb, diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index a94e0df..e1bff77 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -3341,6 +3341,31 @@ static void Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer(PP_Instance inst iface->DownloadManifestToBuffer(instance, data, *callback); } +static int32_t Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest(PP_Instance instance) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->CreatePnaclManifest(instance); +} + +static int32_t Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->CreateJsonManifest(instance, manifest_base_url, sandbox_isa, manifest_data); +} + +static void Pnacl_M25_PPB_NaCl_Private_DestroyManifest(PP_Instance instance, int32_t manifest_id) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + iface->DestroyManifest(instance, manifest_id); +} + +static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->GetManifestProgramURL(instance, manifest_id, full_url, pnacl_options, uses_nonsfi_mode); +} + +static PP_Bool Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->ManifestResolveKey(instance, manifest_id, key, full_url, pnacl_options); +} + /* End wrapper methods for PPB_NaCl_Private_1_0 */ /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */ @@ -5086,7 +5111,12 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .GetManifestURLArgument = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetManifestURLArgument, .IsPNaCl = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_IsPNaCl, .DevInterfacesEnabled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_DevInterfacesEnabled, - .DownloadManifestToBuffer = (void (*)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer + .DownloadManifestToBuffer = (void (*)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer, + .CreatePnaclManifest = (int32_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest, + .CreateJsonManifest = (int32_t (*)(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data))&Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest, + .DestroyManifest = (void (*)(PP_Instance instance, int32_t manifest_id))&Pnacl_M25_PPB_NaCl_Private_DestroyManifest, + .GetManifestProgramURL = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode))&Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL, + .ManifestResolveKey = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options))&Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey }; static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = { |