| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ppapi/native_client/src/trusted/plugin/json_manifest.h" | 9 #include "ppapi/native_client/src/trusted/plugin/json_manifest.h" |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 namespace plugin { | 25 namespace plugin { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 // Top-level section name keys | 28 // Top-level section name keys |
| 29 const char* const kProgramKey = "program"; | 29 const char* const kProgramKey = "program"; |
| 30 const char* const kInterpreterKey = "interpreter"; | 30 const char* const kInterpreterKey = "interpreter"; |
| 31 const char* const kFilesKey = "files"; | 31 const char* const kFilesKey = "files"; |
| 32 | 32 |
| 33 // ISA Dictionary keys | 33 // ISA Dictionary keys |
| 34 const char* const kX8632Key = "x86-32"; | 34 const char* const kX8632Key = "x86-32"; |
| 35 const char* const kX8632NonSFIKey = "x86-32-nonsfi"; |
| 35 const char* const kX8664Key = "x86-64"; | 36 const char* const kX8664Key = "x86-64"; |
| 37 const char* const kX8664NonSFIKey = "x86-64-nonsfi"; |
| 36 const char* const kArmKey = "arm"; | 38 const char* const kArmKey = "arm"; |
| 39 const char* const kArmNonSFIKey = "arm-nonsfi"; |
| 37 const char* const kPortableKey = "portable"; | 40 const char* const kPortableKey = "portable"; |
| 38 | 41 |
| 39 // Url Resolution keys | 42 // Url Resolution keys |
| 40 const char* const kPnaclDebugKey = "pnacl-debug"; | 43 const char* const kPnaclDebugKey = "pnacl-debug"; |
| 41 const char* const kPnaclTranslateKey = "pnacl-translate"; | 44 const char* const kPnaclTranslateKey = "pnacl-translate"; |
| 42 const char* const kUrlKey = "url"; | 45 const char* const kUrlKey = "url"; |
| 43 | 46 |
| 44 // PNaCl keys | 47 // PNaCl keys |
| 45 const char* const kOptLevelKey = "optlevel"; | 48 const char* const kOptLevelKey = "optlevel"; |
| 46 | 49 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 // "files": { | 89 // "files": { |
| 87 // "foo.txt": { | 90 // "foo.txt": { |
| 88 // "portable": {"url": "foo.txt"} | 91 // "portable": {"url": "foo.txt"} |
| 89 // }, | 92 // }, |
| 90 // "bar.txt": { | 93 // "bar.txt": { |
| 91 // "portable": {"url": "bar.txt"} | 94 // "portable": {"url": "bar.txt"} |
| 92 // } | 95 // } |
| 93 // } | 96 // } |
| 94 // } | 97 // } |
| 95 | 98 |
| 99 // Returns the key for the architecture in non-SFI mode. |
| 100 nacl::string GetNonSFIKey(const nacl::string& sandbox_isa) { |
| 101 return sandbox_isa + "-nonsfi"; |
| 102 } |
| 103 |
| 96 // Looks up |property_name| in the vector |valid_names| with length | 104 // Looks up |property_name| in the vector |valid_names| with length |
| 97 // |valid_name_count|. Returns true if |property_name| is found. | 105 // |valid_name_count|. Returns true if |property_name| is found. |
| 98 bool FindMatchingProperty(const nacl::string& property_name, | 106 bool FindMatchingProperty(const nacl::string& property_name, |
| 99 const char** valid_names, | 107 const char** valid_names, |
| 100 size_t valid_name_count) { | 108 size_t valid_name_count) { |
| 101 for (size_t i = 0; i < valid_name_count; ++i) { | 109 for (size_t i = 0; i < valid_name_count; ++i) { |
| 102 if (property_name == valid_names[i]) { | 110 if (property_name == valid_names[i]) { |
| 103 return true; | 111 return true; |
| 104 } | 112 } |
| 105 } | 113 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 // is validated to have keys from within the set of recognized ISAs. Unknown | 260 // is validated to have keys from within the set of recognized ISAs. Unknown |
| 253 // ISAs are allowed, but ignored and warnings are produced. It is also validated | 261 // ISAs are allowed, but ignored and warnings are produced. It is also validated |
| 254 // that it must have an entry to match the ISA specified in |sandbox_isa| or | 262 // that it must have an entry to match the ISA specified in |sandbox_isa| or |
| 255 // have a fallback 'portable' entry if there is no match. Returns true if | 263 // have a fallback 'portable' entry if there is no match. Returns true if |
| 256 // |dictionary| is an ISA to URL map. Sets |error_info| to something | 264 // |dictionary| is an ISA to URL map. Sets |error_info| to something |
| 257 // descriptive if it fails. | 265 // descriptive if it fails. |
| 258 bool IsValidISADictionary(const Json::Value& dictionary, | 266 bool IsValidISADictionary(const Json::Value& dictionary, |
| 259 const nacl::string& parent_key, | 267 const nacl::string& parent_key, |
| 260 const nacl::string& sandbox_isa, | 268 const nacl::string& sandbox_isa, |
| 261 bool must_find_matching_entry, | 269 bool must_find_matching_entry, |
| 270 bool nonsfi_enabled, |
| 262 ErrorInfo* error_info) { | 271 ErrorInfo* error_info) { |
| 263 if (error_info == NULL) return false; | 272 if (error_info == NULL) return false; |
| 264 | 273 |
| 265 // An ISA to URL dictionary has to be an object. | 274 // An ISA to URL dictionary has to be an object. |
| 266 if (!dictionary.isObject()) { | 275 if (!dictionary.isObject()) { |
| 267 error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, | 276 error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, |
| 268 nacl::string("manifest: ") + parent_key + | 277 nacl::string("manifest: ") + parent_key + |
| 269 " property is not an ISA to URL dictionary"); | 278 " property is not an ISA to URL dictionary"); |
| 270 return false; | 279 return false; |
| 271 } | 280 } |
| 272 // Build the set of reserved ISA dictionary keys. | 281 // Build the set of reserved ISA dictionary keys. |
| 273 const char** isaProperties; | 282 const char** isaProperties; |
| 274 size_t isaPropertiesLength; | 283 size_t isaPropertiesLength; |
| 275 if (sandbox_isa == kPortableKey) { | 284 if (sandbox_isa == kPortableKey) { |
| 276 // The known values for PNaCl ISA dictionaries in the manifest. | 285 // The known values for PNaCl ISA dictionaries in the manifest. |
| 277 static const char* kPnaclManifestISAProperties[] = { | 286 static const char* kPnaclManifestISAProperties[] = { |
| 278 kPortableKey | 287 kPortableKey |
| 279 }; | 288 }; |
| 280 isaProperties = kPnaclManifestISAProperties; | 289 isaProperties = kPnaclManifestISAProperties; |
| 281 isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); | 290 isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); |
| 282 } else { | 291 } else { |
| 283 // The known values for NaCl ISA dictionaries in the manifest. | 292 // The known values for NaCl ISA dictionaries in the manifest. |
| 284 static const char* kNaClManifestISAProperties[] = { | 293 static const char* kNaClManifestISAProperties[] = { |
| 285 kX8632Key, | 294 kX8632Key, |
| 295 kX8632NonSFIKey, |
| 286 kX8664Key, | 296 kX8664Key, |
| 297 kX8664NonSFIKey, |
| 287 kArmKey, | 298 kArmKey, |
| 299 kArmNonSFIKey, |
| 288 // "portable" is here to allow checking that, if present, it can | 300 // "portable" is here to allow checking that, if present, it can |
| 289 // only refer to an URL, such as for a data file, and not to | 301 // only refer to an URL, such as for a data file, and not to |
| 290 // "pnacl-translate", which would cause the creation of a nexe. | 302 // "pnacl-translate", which would cause the creation of a nexe. |
| 291 kPortableKey | 303 kPortableKey |
| 292 }; | 304 }; |
| 293 isaProperties = kNaClManifestISAProperties; | 305 isaProperties = kNaClManifestISAProperties; |
| 294 isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); | 306 isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); |
| 295 } | 307 } |
| 296 // Check that entries in the dictionary are structurally correct. | 308 // Check that entries in the dictionary are structurally correct. |
| 297 Json::Value::Members members = dictionary.getMemberNames(); | 309 Json::Value::Members members = dictionary.getMemberNames(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 error_info->SetReport( | 358 error_info->SetReport( |
| 347 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, | 359 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, |
| 348 nacl::string("manifest: no version of ") + parent_key + | 360 nacl::string("manifest: no version of ") + parent_key + |
| 349 " given for portable."); | 361 " given for portable."); |
| 350 return false; | 362 return false; |
| 351 } | 363 } |
| 352 } else if (must_find_matching_entry) { | 364 } else if (must_find_matching_entry) { |
| 353 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include | 365 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include |
| 354 // micro-architectures that can resolve to multiple valid sandboxes. | 366 // micro-architectures that can resolve to multiple valid sandboxes. |
| 355 bool has_isa = dictionary.isMember(sandbox_isa); | 367 bool has_isa = dictionary.isMember(sandbox_isa); |
| 368 bool has_nonsfi_isa = |
| 369 nonsfi_enabled && dictionary.isMember(GetNonSFIKey(sandbox_isa)); |
| 356 bool has_portable = dictionary.isMember(kPortableKey); | 370 bool has_portable = dictionary.isMember(kPortableKey); |
| 357 | 371 |
| 358 if (!has_isa && !has_portable) { | 372 if (!has_isa && !has_nonsfi_isa && !has_portable) { |
| 359 error_info->SetReport( | 373 error_info->SetReport( |
| 360 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, | 374 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, |
| 361 nacl::string("manifest: no version of ") + parent_key + | 375 nacl::string("manifest: no version of ") + parent_key + |
| 362 " given for current arch and no portable version found."); | 376 " given for current arch and no portable version found."); |
| 363 return false; | 377 return false; |
| 364 } | 378 } |
| 365 } | 379 } |
| 366 | 380 |
| 367 return true; | 381 return true; |
| 368 } | 382 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 return false; | 446 return false; |
| 433 } | 447 } |
| 434 | 448 |
| 435 // Validate the program section. | 449 // Validate the program section. |
| 436 // There must be a matching (portable or sandbox_isa_) entry for program for | 450 // There must be a matching (portable or sandbox_isa_) entry for program for |
| 437 // NaCl. | 451 // NaCl. |
| 438 if (!IsValidISADictionary(dictionary_[kProgramKey], | 452 if (!IsValidISADictionary(dictionary_[kProgramKey], |
| 439 kProgramKey, | 453 kProgramKey, |
| 440 sandbox_isa_, | 454 sandbox_isa_, |
| 441 true, | 455 true, |
| 456 nonsfi_enabled_, |
| 442 error_info)) { | 457 error_info)) { |
| 443 return false; | 458 return false; |
| 444 } | 459 } |
| 445 | 460 |
| 446 // Validate the interpreter section (if given). | 461 // Validate the interpreter section (if given). |
| 447 // There must be a matching (portable or sandbox_isa_) entry for interpreter | 462 // There must be a matching (portable or sandbox_isa_) entry for interpreter |
| 448 // for NaCl. | 463 // for NaCl. |
| 449 if (dictionary_.isMember(kInterpreterKey)) { | 464 if (dictionary_.isMember(kInterpreterKey)) { |
| 450 if (!IsValidISADictionary(dictionary_[kInterpreterKey], | 465 if (!IsValidISADictionary(dictionary_[kInterpreterKey], |
| 451 kInterpreterKey, | 466 kInterpreterKey, |
| 452 sandbox_isa_, | 467 sandbox_isa_, |
| 453 true, | 468 true, |
| 469 nonsfi_enabled_, |
| 454 error_info)) { | 470 error_info)) { |
| 455 return false; | 471 return false; |
| 456 } | 472 } |
| 457 } | 473 } |
| 458 | 474 |
| 459 // Validate the file dictionary (if given). | 475 // Validate the file dictionary (if given). |
| 460 // The "files" key does not require a matching (portable or sandbox_isa_) | 476 // The "files" key does not require a matching (portable or sandbox_isa_) |
| 461 // entry at schema validation time for NaCl. This allows manifests to specify | 477 // entry at schema validation time for NaCl. This allows manifests to specify |
| 462 // resources that are only loaded for a particular sandbox_isa. | 478 // resources that are only loaded for a particular sandbox_isa. |
| 463 if (dictionary_.isMember(kFilesKey)) { | 479 if (dictionary_.isMember(kFilesKey)) { |
| 464 const Json::Value& files = dictionary_[kFilesKey]; | 480 const Json::Value& files = dictionary_[kFilesKey]; |
| 465 if (!files.isObject()) { | 481 if (!files.isObject()) { |
| 466 error_info->SetReport( | 482 error_info->SetReport( |
| 467 PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, | 483 PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, |
| 468 nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); | 484 nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); |
| 469 } | 485 } |
| 470 Json::Value::Members members = files.getMemberNames(); | 486 Json::Value::Members members = files.getMemberNames(); |
| 471 for (size_t i = 0; i < members.size(); ++i) { | 487 for (size_t i = 0; i < members.size(); ++i) { |
| 472 nacl::string file_name = members[i]; | 488 nacl::string file_name = members[i]; |
| 473 if (!IsValidISADictionary(files[file_name], | 489 if (!IsValidISADictionary(files[file_name], |
| 474 file_name, | 490 file_name, |
| 475 sandbox_isa_, | 491 sandbox_isa_, |
| 476 false, | 492 false, |
| 493 nonsfi_enabled_, |
| 477 error_info)) { | 494 error_info)) { |
| 478 return false; | 495 return false; |
| 479 } | 496 } |
| 480 } | 497 } |
| 481 } | 498 } |
| 482 | 499 |
| 483 return true; | 500 return true; |
| 484 } | 501 } |
| 485 | 502 |
| 486 bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, | 503 bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, |
| 487 const nacl::string& parent_key, | 504 const nacl::string& parent_key, |
| 488 nacl::string* url, | 505 nacl::string* url, |
| 489 PnaclOptions* pnacl_options, | 506 PnaclOptions* pnacl_options, |
| 507 bool* uses_nonsfi_mode, |
| 490 ErrorInfo* error_info) const { | 508 ErrorInfo* error_info) const { |
| 491 DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); | 509 DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); |
| 492 | 510 |
| 493 // When the application actually requests a resolved URL, we must have | 511 // When the application actually requests a resolved URL, we must have |
| 494 // a matching entry (sandbox_isa_ or portable) for NaCl. | 512 // a matching entry (sandbox_isa_ or portable) for NaCl. |
| 495 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, | 513 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, |
| 496 error_info)) { | 514 nonsfi_enabled_, error_info)) { |
| 497 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 515 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
| 498 "architecture " + sandbox_isa_ + | 516 "architecture " + sandbox_isa_ + |
| 499 " is not found for file " + parent_key); | 517 " is not found for file " + parent_key); |
| 500 return false; | 518 return false; |
| 501 } | 519 } |
| 502 | 520 |
| 503 *url = ""; | |
| 504 | |
| 505 // The call to IsValidISADictionary() above guarantees that either | 521 // The call to IsValidISADictionary() above guarantees that either |
| 506 // sandbox_isa_ or kPortableKey is present in the dictionary. | 522 // sandbox_isa_, its nonsfi mode, or kPortableKey is present in the |
| 507 bool has_portable = dictionary.isMember(kPortableKey); | 523 // dictionary. |
| 508 bool has_isa = dictionary.isMember(sandbox_isa_); | 524 *uses_nonsfi_mode = false; |
| 509 nacl::string chosen_isa; | 525 nacl::string chosen_isa; |
| 510 if ((sandbox_isa_ == kPortableKey) || (has_portable && !has_isa)) { | 526 if (sandbox_isa_ == kPortableKey) { |
| 511 chosen_isa = kPortableKey; | 527 chosen_isa = kPortableKey; |
| 512 } else { | 528 } else { |
| 513 chosen_isa = sandbox_isa_; | 529 nacl::string nonsfi_isa = GetNonSFIKey(sandbox_isa_); |
| 530 if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) { |
| 531 chosen_isa = nonsfi_isa; |
| 532 *uses_nonsfi_mode = true; |
| 533 } else if (dictionary.isMember(sandbox_isa_)) { |
| 534 chosen_isa = sandbox_isa_; |
| 535 } else if (dictionary.isMember(kPortableKey)) { |
| 536 chosen_isa = kPortableKey; |
| 537 } else { |
| 538 // Should not reach here, because the earlier IsValidISADictionary() |
| 539 // call checked that the manifest covers the current architecture. |
| 540 DCHECK(false); |
| 541 } |
| 514 } | 542 } |
| 543 |
| 515 const Json::Value& isa_spec = dictionary[chosen_isa]; | 544 const Json::Value& isa_spec = dictionary[chosen_isa]; |
| 516 // If the PNaCl debug flag is turned on, look for pnacl-debug entries first. | 545 // If the PNaCl debug flag is turned on, look for pnacl-debug entries first. |
| 517 // If found, mark that it is a debug URL. Otherwise, fall back to | 546 // If found, mark that it is a debug URL. Otherwise, fall back to |
| 518 // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL. | 547 // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL. |
| 519 if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) { | 548 if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) { |
| 520 GrabUrlAndPnaclOptions(isa_spec[kPnaclDebugKey], url, pnacl_options); | 549 GrabUrlAndPnaclOptions(isa_spec[kPnaclDebugKey], url, pnacl_options); |
| 521 pnacl_options->set_debug(true); | 550 pnacl_options->set_debug(true); |
| 522 } else if (isa_spec.isMember(kPnaclTranslateKey)) { | 551 } else if (isa_spec.isMember(kPnaclTranslateKey)) { |
| 523 GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); | 552 GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); |
| 524 } else { | 553 } else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 536 PnaclOptions* pnacl_options, | 565 PnaclOptions* pnacl_options, |
| 537 ErrorInfo* error_info) const { | 566 ErrorInfo* error_info) const { |
| 538 DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL); | 567 DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL); |
| 539 if (!dictionary.isMember(key)) { | 568 if (!dictionary.isMember(key)) { |
| 540 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 569 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
| 541 "file key not found in manifest"); | 570 "file key not found in manifest"); |
| 542 return false; | 571 return false; |
| 543 } | 572 } |
| 544 const Json::Value& isa_dict = dictionary[key]; | 573 const Json::Value& isa_dict = dictionary[key]; |
| 545 nacl::string relative_url; | 574 nacl::string relative_url; |
| 575 bool uses_nonsfi_mode; |
| 546 if (!GetURLFromISADictionary(isa_dict, key, &relative_url, | 576 if (!GetURLFromISADictionary(isa_dict, key, &relative_url, |
| 547 pnacl_options, error_info)) { | 577 pnacl_options, &uses_nonsfi_mode, error_info)) { |
| 548 return false; | 578 return false; |
| 549 } | 579 } |
| 550 return ResolveURL(relative_url, full_url, error_info); | 580 return ResolveURL(relative_url, full_url, error_info); |
| 551 } | 581 } |
| 552 | 582 |
| 553 bool JsonManifest::ResolveURL(const nacl::string& relative_url, | 583 bool JsonManifest::ResolveURL(const nacl::string& relative_url, |
| 554 nacl::string* full_url, | 584 nacl::string* full_url, |
| 555 ErrorInfo* error_info) const { | 585 ErrorInfo* error_info) const { |
| 556 // The contents of the manifest are resolved relative to the manifest URL. | 586 // The contents of the manifest are resolved relative to the manifest URL. |
| 557 CHECK(url_util_ != NULL); | 587 CHECK(url_util_ != NULL); |
| 558 pp::Var resolved_url = | 588 pp::Var resolved_url = |
| 559 url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), | 589 url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), |
| 560 relative_url); | 590 relative_url); |
| 561 if (!resolved_url.is_string()) { | 591 if (!resolved_url.is_string()) { |
| 562 error_info->SetReport( | 592 error_info->SetReport( |
| 563 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 593 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
| 564 "could not resolve url '" + relative_url + | 594 "could not resolve url '" + relative_url + |
| 565 "' relative to manifest base url '" + manifest_base_url_.c_str() + | 595 "' relative to manifest base url '" + manifest_base_url_.c_str() + |
| 566 "'."); | 596 "'."); |
| 567 return false; | 597 return false; |
| 568 } | 598 } |
| 569 *full_url = resolved_url.AsString(); | 599 *full_url = resolved_url.AsString(); |
| 570 return true; | 600 return true; |
| 571 } | 601 } |
| 572 | 602 |
| 573 bool JsonManifest::GetProgramURL(nacl::string* full_url, | 603 bool JsonManifest::GetProgramURL(nacl::string* full_url, |
| 574 PnaclOptions* pnacl_options, | 604 PnaclOptions* pnacl_options, |
| 605 bool* uses_nonsfi_mode, |
| 575 ErrorInfo* error_info) const { | 606 ErrorInfo* error_info) const { |
| 576 if (full_url == NULL || pnacl_options == NULL || error_info == NULL) | 607 if (full_url == NULL || pnacl_options == NULL || error_info == NULL) |
| 577 return false; | 608 return false; |
| 578 | 609 |
| 579 Json::Value program = dictionary_[kProgramKey]; | 610 const Json::Value& program = dictionary_[kProgramKey]; |
| 580 | 611 |
| 581 nacl::string nexe_url; | 612 nacl::string nexe_url; |
| 582 nacl::string error_string; | 613 nacl::string error_string; |
| 583 | 614 |
| 584 if (!GetURLFromISADictionary(program, | 615 if (!GetURLFromISADictionary(program, |
| 585 kProgramKey, | 616 kProgramKey, |
| 586 &nexe_url, | 617 &nexe_url, |
| 587 pnacl_options, | 618 pnacl_options, |
| 619 uses_nonsfi_mode, |
| 588 error_info)) { | 620 error_info)) { |
| 589 return false; | 621 return false; |
| 590 } | 622 } |
| 591 | 623 |
| 592 return ResolveURL(nexe_url, full_url, error_info); | 624 return ResolveURL(nexe_url, full_url, error_info); |
| 593 } | 625 } |
| 594 | 626 |
| 595 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { | 627 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { |
| 596 if (!dictionary_.isMember(kFilesKey)) { | 628 if (!dictionary_.isMember(kFilesKey)) { |
| 597 // trivial success: no keys when there is no "files" section. | 629 // trivial success: no keys when there is no "files" section. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 if (!files.isMember(rest)) { | 680 if (!files.isMember(rest)) { |
| 649 error_info->SetReport( | 681 error_info->SetReport( |
| 650 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 682 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
| 651 nacl::string("ResolveKey: no such \"files\" entry: ") + key); | 683 nacl::string("ResolveKey: no such \"files\" entry: ") + key); |
| 652 return false; | 684 return false; |
| 653 } | 685 } |
| 654 return GetKeyUrl(files, rest, full_url, pnacl_options, error_info); | 686 return GetKeyUrl(files, rest, full_url, pnacl_options, error_info); |
| 655 } | 687 } |
| 656 | 688 |
| 657 } // namespace plugin | 689 } // namespace plugin |
| OLD | NEW |