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 kPnaclTranslateKey = "pnacl-translate"; | 43 const char* const kPnaclTranslateKey = "pnacl-translate"; |
41 const char* const kUrlKey = "url"; | 44 const char* const kUrlKey = "url"; |
42 | 45 |
43 // PNaCl keys | 46 // PNaCl keys |
44 const char* const kOptLevelKey = "optlevel"; | 47 const char* const kOptLevelKey = "optlevel"; |
45 | 48 |
46 // Sample NaCl manifest file: | 49 // Sample NaCl manifest file: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 // "files": { | 85 // "files": { |
83 // "foo.txt": { | 86 // "foo.txt": { |
84 // "portable": {"url": "foo.txt"} | 87 // "portable": {"url": "foo.txt"} |
85 // }, | 88 // }, |
86 // "bar.txt": { | 89 // "bar.txt": { |
87 // "portable": {"url": "bar.txt"} | 90 // "portable": {"url": "bar.txt"} |
88 // } | 91 // } |
89 // } | 92 // } |
90 // } | 93 // } |
91 | 94 |
95 // Returns the key for the architecture in non-SFI mode. | |
96 nacl::string GetNonSFIKey(const nacl::string& sandbox_isa) { | |
97 return sandbox_isa + "-nonsfi"; | |
98 } | |
99 | |
92 // Looks up |property_name| in the vector |valid_names| with length | 100 // Looks up |property_name| in the vector |valid_names| with length |
93 // |valid_name_count|. Returns true if |property_name| is found. | 101 // |valid_name_count|. Returns true if |property_name| is found. |
94 bool FindMatchingProperty(const nacl::string& property_name, | 102 bool FindMatchingProperty(const nacl::string& property_name, |
95 const char** valid_names, | 103 const char** valid_names, |
96 size_t valid_name_count) { | 104 size_t valid_name_count) { |
97 for (size_t i = 0; i < valid_name_count; ++i) { | 105 for (size_t i = 0; i < valid_name_count; ++i) { |
98 if (property_name == valid_names[i]) { | 106 if (property_name == valid_names[i]) { |
99 return true; | 107 return true; |
100 } | 108 } |
101 } | 109 } |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 // is validated to have keys from within the set of recognized ISAs. Unknown | 251 // is validated to have keys from within the set of recognized ISAs. Unknown |
244 // ISAs are allowed, but ignored and warnings are produced. It is also validated | 252 // ISAs are allowed, but ignored and warnings are produced. It is also validated |
245 // that it must have an entry to match the ISA specified in |sandbox_isa| or | 253 // that it must have an entry to match the ISA specified in |sandbox_isa| or |
246 // have a fallback 'portable' entry if there is no match. Returns true if | 254 // have a fallback 'portable' entry if there is no match. Returns true if |
247 // |dictionary| is an ISA to URL map. Sets |error_info| to something | 255 // |dictionary| is an ISA to URL map. Sets |error_info| to something |
248 // descriptive if it fails. | 256 // descriptive if it fails. |
249 bool IsValidISADictionary(const Json::Value& dictionary, | 257 bool IsValidISADictionary(const Json::Value& dictionary, |
250 const nacl::string& parent_key, | 258 const nacl::string& parent_key, |
251 const nacl::string& sandbox_isa, | 259 const nacl::string& sandbox_isa, |
252 bool must_find_matching_entry, | 260 bool must_find_matching_entry, |
261 bool nonsfi_enabled, | |
253 ErrorInfo* error_info) { | 262 ErrorInfo* error_info) { |
254 if (error_info == NULL) return false; | 263 if (error_info == NULL) return false; |
255 | 264 |
256 // An ISA to URL dictionary has to be an object. | 265 // An ISA to URL dictionary has to be an object. |
257 if (!dictionary.isObject()) { | 266 if (!dictionary.isObject()) { |
258 error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, | 267 error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, |
259 nacl::string("manifest: ") + parent_key + | 268 nacl::string("manifest: ") + parent_key + |
260 " property is not an ISA to URL dictionary"); | 269 " property is not an ISA to URL dictionary"); |
261 return false; | 270 return false; |
262 } | 271 } |
263 // Build the set of reserved ISA dictionary keys. | 272 // Build the set of reserved ISA dictionary keys. |
264 const char** isaProperties; | 273 const char** isaProperties; |
265 size_t isaPropertiesLength; | 274 size_t isaPropertiesLength; |
266 if (sandbox_isa == kPortableKey) { | 275 if (sandbox_isa == kPortableKey) { |
267 // The known values for PNaCl ISA dictionaries in the manifest. | 276 // The known values for PNaCl ISA dictionaries in the manifest. |
268 static const char* kPnaclManifestISAProperties[] = { | 277 static const char* kPnaclManifestISAProperties[] = { |
269 kPortableKey | 278 kPortableKey |
270 }; | 279 }; |
271 isaProperties = kPnaclManifestISAProperties; | 280 isaProperties = kPnaclManifestISAProperties; |
272 isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); | 281 isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); |
273 } else { | 282 } else { |
274 // The known values for NaCl ISA dictionaries in the manifest. | 283 // The known values for NaCl ISA dictionaries in the manifest. |
275 static const char* kNaClManifestISAProperties[] = { | 284 static const char* kNaClManifestISAProperties[] = { |
276 kX8632Key, | 285 kX8632Key, |
286 kX8632NonSFIKey, | |
277 kX8664Key, | 287 kX8664Key, |
288 kX8664NonSFIKey, | |
278 kArmKey, | 289 kArmKey, |
290 kArmNonSFIKey, | |
279 // "portable" is here to allow checking that, if present, it can | 291 // "portable" is here to allow checking that, if present, it can |
280 // only refer to an URL, such as for a data file, and not to | 292 // only refer to an URL, such as for a data file, and not to |
281 // "pnacl-translate", which would cause the creation of a nexe. | 293 // "pnacl-translate", which would cause the creation of a nexe. |
282 kPortableKey | 294 kPortableKey |
283 }; | 295 }; |
284 isaProperties = kNaClManifestISAProperties; | 296 isaProperties = kNaClManifestISAProperties; |
285 isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); | 297 isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); |
286 } | 298 } |
287 // Check that entries in the dictionary are structurally correct. | 299 // Check that entries in the dictionary are structurally correct. |
288 Json::Value::Members members = dictionary.getMemberNames(); | 300 Json::Value::Members members = dictionary.getMemberNames(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 error_info->SetReport( | 348 error_info->SetReport( |
337 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, | 349 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, |
338 nacl::string("manifest: no version of ") + parent_key + | 350 nacl::string("manifest: no version of ") + parent_key + |
339 " given for portable."); | 351 " given for portable."); |
340 return false; | 352 return false; |
341 } | 353 } |
342 } else if (must_find_matching_entry) { | 354 } else if (must_find_matching_entry) { |
343 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include | 355 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include |
344 // micro-architectures that can resolve to multiple valid sandboxes. | 356 // micro-architectures that can resolve to multiple valid sandboxes. |
345 bool has_isa = dictionary.isMember(sandbox_isa); | 357 bool has_isa = dictionary.isMember(sandbox_isa); |
358 bool has_nonsfi_isa = | |
359 nonsfi_enabled && dictionary.isMember(GetNonSFIKey(sandbox_isa)); | |
346 bool has_portable = dictionary.isMember(kPortableKey); | 360 bool has_portable = dictionary.isMember(kPortableKey); |
347 | 361 |
348 if (!has_isa && !has_portable) { | 362 if (!has_isa && !has_nonsfi_isa && !has_portable) { |
349 error_info->SetReport( | 363 error_info->SetReport( |
350 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, | 364 PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, |
351 nacl::string("manifest: no version of ") + parent_key + | 365 nacl::string("manifest: no version of ") + parent_key + |
352 " given for current arch and no portable version found."); | 366 " given for current arch and no portable version found."); |
353 return false; | 367 return false; |
354 } | 368 } |
355 } | 369 } |
356 | 370 |
357 return true; | 371 return true; |
358 } | 372 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 return false; | 435 return false; |
422 } | 436 } |
423 | 437 |
424 // Validate the program section. | 438 // Validate the program section. |
425 // There must be a matching (portable or sandbox_isa_) entry for program for | 439 // There must be a matching (portable or sandbox_isa_) entry for program for |
426 // NaCl. | 440 // NaCl. |
427 if (!IsValidISADictionary(dictionary_[kProgramKey], | 441 if (!IsValidISADictionary(dictionary_[kProgramKey], |
428 kProgramKey, | 442 kProgramKey, |
429 sandbox_isa_, | 443 sandbox_isa_, |
430 true, | 444 true, |
445 nonsfi_enabled_, | |
431 error_info)) { | 446 error_info)) { |
432 return false; | 447 return false; |
433 } | 448 } |
434 | 449 |
435 // Validate the interpreter section (if given). | 450 // Validate the interpreter section (if given). |
436 // There must be a matching (portable or sandbox_isa_) entry for interpreter | 451 // There must be a matching (portable or sandbox_isa_) entry for interpreter |
437 // for NaCl. | 452 // for NaCl. |
438 if (dictionary_.isMember(kInterpreterKey)) { | 453 if (dictionary_.isMember(kInterpreterKey)) { |
439 if (!IsValidISADictionary(dictionary_[kInterpreterKey], | 454 if (!IsValidISADictionary(dictionary_[kInterpreterKey], |
440 kInterpreterKey, | 455 kInterpreterKey, |
441 sandbox_isa_, | 456 sandbox_isa_, |
442 true, | 457 true, |
458 nonsfi_enabled_, | |
443 error_info)) { | 459 error_info)) { |
444 return false; | 460 return false; |
445 } | 461 } |
446 } | 462 } |
447 | 463 |
448 // Validate the file dictionary (if given). | 464 // Validate the file dictionary (if given). |
449 // The "files" key does not require a matching (portable or sandbox_isa_) | 465 // The "files" key does not require a matching (portable or sandbox_isa_) |
450 // entry at schema validation time for NaCl. This allows manifests to specify | 466 // entry at schema validation time for NaCl. This allows manifests to specify |
451 // resources that are only loaded for a particular sandbox_isa. | 467 // resources that are only loaded for a particular sandbox_isa. |
452 if (dictionary_.isMember(kFilesKey)) { | 468 if (dictionary_.isMember(kFilesKey)) { |
453 const Json::Value& files = dictionary_[kFilesKey]; | 469 const Json::Value& files = dictionary_[kFilesKey]; |
454 if (!files.isObject()) { | 470 if (!files.isObject()) { |
455 error_info->SetReport( | 471 error_info->SetReport( |
456 PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, | 472 PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, |
457 nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); | 473 nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); |
458 } | 474 } |
459 Json::Value::Members members = files.getMemberNames(); | 475 Json::Value::Members members = files.getMemberNames(); |
460 for (size_t i = 0; i < members.size(); ++i) { | 476 for (size_t i = 0; i < members.size(); ++i) { |
461 nacl::string file_name = members[i]; | 477 nacl::string file_name = members[i]; |
462 if (!IsValidISADictionary(files[file_name], | 478 if (!IsValidISADictionary(files[file_name], |
463 file_name, | 479 file_name, |
464 sandbox_isa_, | 480 sandbox_isa_, |
465 false, | 481 false, |
482 nonsfi_enabled_, | |
466 error_info)) { | 483 error_info)) { |
467 return false; | 484 return false; |
468 } | 485 } |
469 } | 486 } |
470 } | 487 } |
471 | 488 |
472 return true; | 489 return true; |
473 } | 490 } |
474 | 491 |
475 bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, | 492 bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, |
476 const nacl::string& parent_key, | 493 const nacl::string& parent_key, |
477 nacl::string* url, | 494 nacl::string* url, |
478 PnaclOptions* pnacl_options, | 495 PnaclOptions* pnacl_options, |
496 bool* uses_nonsfi_mode, | |
479 ErrorInfo* error_info) const { | 497 ErrorInfo* error_info) const { |
480 DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); | 498 DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); |
481 | 499 |
482 // When the application actually requests a resolved URL, we must have | 500 // When the application actually requests a resolved URL, we must have |
483 // a matching entry (sandbox_isa_ or portable) for NaCl. | 501 // a matching entry (sandbox_isa_ or portable) for NaCl. |
484 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, | 502 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, |
485 error_info)) { | 503 nonsfi_enabled_, error_info)) { |
486 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 504 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
487 "architecture " + sandbox_isa_ + | 505 "architecture " + sandbox_isa_ + |
488 " is not found for file " + parent_key); | 506 " is not found for file " + parent_key); |
489 return false; | 507 return false; |
490 } | 508 } |
491 | 509 |
492 *url = ""; | 510 *uses_nonsfi_mode = false; |
493 | |
494 // The call to IsValidISADictionary() above guarantees that either | |
Mark Seaborn
2014/03/05 17:44:32
Please keep this comment in some form. See commen
hidehiko
2014/03/06 05:31:11
Done.
| |
495 // sandbox_isa_ or kPortableKey is present in the dictionary. | |
496 bool has_portable = dictionary.isMember(kPortableKey); | |
497 bool has_isa = dictionary.isMember(sandbox_isa_); | |
498 nacl::string chosen_isa; | 511 nacl::string chosen_isa; |
499 if ((sandbox_isa_ == kPortableKey) || (has_portable && !has_isa)) { | 512 if (sandbox_isa_ == kPortableKey) { |
500 chosen_isa = kPortableKey; | 513 chosen_isa = kPortableKey; |
501 } else { | 514 } else { |
502 chosen_isa = sandbox_isa_; | 515 nacl::string nonsfi_isa = GetNonSFIKey(sandbox_isa_); |
516 if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) { | |
517 chosen_isa = nonsfi_isa; | |
518 *uses_nonsfi_mode = true; | |
519 } else if (dictionary.isMember(sandbox_isa_)) { | |
520 chosen_isa = sandbox_isa_; | |
521 } else if (dictionary.isMember(kPortableKey)) { | |
522 chosen_isa = kPortableKey; | |
523 } else { | |
524 DCHECK(false); // Should not reach here. | |
Mark Seaborn
2014/03/05 17:44:32
Can you add an explanation like: "because the earl
hidehiko
2014/03/06 05:31:11
Done.
| |
525 } | |
503 } | 526 } |
527 | |
504 const Json::Value& isa_spec = dictionary[chosen_isa]; | 528 const Json::Value& isa_spec = dictionary[chosen_isa]; |
505 // Check if this requires a pnacl-translate, otherwise just grab the URL. | 529 // Check if this requires a pnacl-translate, otherwise just grab the URL. |
506 // We may have pnacl-translate for isa-specific bitcode for CPU tuning. | 530 // We may have pnacl-translate for isa-specific bitcode for CPU tuning. |
507 if (isa_spec.isMember(kPnaclTranslateKey)) { | 531 if (isa_spec.isMember(kPnaclTranslateKey)) { |
508 // PNaCl | 532 // PNaCl |
509 GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); | 533 GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); |
510 pnacl_options->set_translate(true); | 534 pnacl_options->set_translate(true); |
511 } else { | 535 } else { |
512 // NaCl | 536 // NaCl |
513 *url = isa_spec[kUrlKey].asString(); | 537 *url = isa_spec[kUrlKey].asString(); |
514 pnacl_options->set_translate(false); | 538 pnacl_options->set_translate(false); |
515 } | 539 } |
516 | 540 |
517 return true; | 541 return true; |
518 } | 542 } |
519 | 543 |
520 bool JsonManifest::GetKeyUrl(const Json::Value& dictionary, | 544 bool JsonManifest::GetKeyUrl(const Json::Value& dictionary, |
521 const nacl::string& key, | 545 const nacl::string& key, |
522 nacl::string* full_url, | 546 nacl::string* full_url, |
523 PnaclOptions* pnacl_options, | 547 PnaclOptions* pnacl_options, |
524 ErrorInfo* error_info) const { | 548 ErrorInfo* error_info) const { |
525 DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL); | 549 DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL); |
526 if (!dictionary.isMember(key)) { | 550 if (!dictionary.isMember(key)) { |
527 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 551 error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
528 "file key not found in manifest"); | 552 "file key not found in manifest"); |
529 return false; | 553 return false; |
530 } | 554 } |
531 const Json::Value& isa_dict = dictionary[key]; | 555 const Json::Value& isa_dict = dictionary[key]; |
532 nacl::string relative_url; | 556 nacl::string relative_url; |
557 bool uses_nonsfi_mode; | |
533 if (!GetURLFromISADictionary(isa_dict, key, &relative_url, | 558 if (!GetURLFromISADictionary(isa_dict, key, &relative_url, |
534 pnacl_options, error_info)) { | 559 pnacl_options, &uses_nonsfi_mode, error_info)) { |
535 return false; | 560 return false; |
536 } | 561 } |
537 return ResolveURL(relative_url, full_url, error_info); | 562 return ResolveURL(relative_url, full_url, error_info); |
538 } | 563 } |
539 | 564 |
540 bool JsonManifest::ResolveURL(const nacl::string& relative_url, | 565 bool JsonManifest::ResolveURL(const nacl::string& relative_url, |
541 nacl::string* full_url, | 566 nacl::string* full_url, |
542 ErrorInfo* error_info) const { | 567 ErrorInfo* error_info) const { |
543 // The contents of the manifest are resolved relative to the manifest URL. | 568 // The contents of the manifest are resolved relative to the manifest URL. |
544 CHECK(url_util_ != NULL); | 569 CHECK(url_util_ != NULL); |
545 pp::Var resolved_url = | 570 pp::Var resolved_url = |
546 url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), | 571 url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), |
547 relative_url); | 572 relative_url); |
548 if (!resolved_url.is_string()) { | 573 if (!resolved_url.is_string()) { |
549 error_info->SetReport( | 574 error_info->SetReport( |
550 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 575 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
551 "could not resolve url '" + relative_url + | 576 "could not resolve url '" + relative_url + |
552 "' relative to manifest base url '" + manifest_base_url_.c_str() + | 577 "' relative to manifest base url '" + manifest_base_url_.c_str() + |
553 "'."); | 578 "'."); |
554 return false; | 579 return false; |
555 } | 580 } |
556 *full_url = resolved_url.AsString(); | 581 *full_url = resolved_url.AsString(); |
557 return true; | 582 return true; |
558 } | 583 } |
559 | 584 |
560 bool JsonManifest::GetProgramURL(nacl::string* full_url, | 585 bool JsonManifest::GetProgramURL(nacl::string* full_url, |
561 PnaclOptions* pnacl_options, | 586 PnaclOptions* pnacl_options, |
587 bool* uses_nonsfi_mode, | |
562 ErrorInfo* error_info) const { | 588 ErrorInfo* error_info) const { |
563 if (full_url == NULL || pnacl_options == NULL || error_info == NULL) | 589 if (full_url == NULL || pnacl_options == NULL || error_info == NULL) |
564 return false; | 590 return false; |
565 | 591 |
566 Json::Value program = dictionary_[kProgramKey]; | 592 const Json::Value& program = dictionary_[kProgramKey]; |
567 | 593 |
568 nacl::string nexe_url; | 594 nacl::string nexe_url; |
569 nacl::string error_string; | 595 nacl::string error_string; |
570 | 596 |
571 if (!GetURLFromISADictionary(program, | 597 if (!GetURLFromISADictionary(program, |
572 kProgramKey, | 598 kProgramKey, |
573 &nexe_url, | 599 &nexe_url, |
574 pnacl_options, | 600 pnacl_options, |
601 uses_nonsfi_mode, | |
575 error_info)) { | 602 error_info)) { |
576 return false; | 603 return false; |
577 } | 604 } |
578 | 605 |
579 return ResolveURL(nexe_url, full_url, error_info); | 606 return ResolveURL(nexe_url, full_url, error_info); |
580 } | 607 } |
581 | 608 |
582 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { | 609 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { |
583 if (!dictionary_.isMember(kFilesKey)) { | 610 if (!dictionary_.isMember(kFilesKey)) { |
584 // trivial success: no keys when there is no "files" section. | 611 // trivial success: no keys when there is no "files" section. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 if (!files.isMember(rest)) { | 662 if (!files.isMember(rest)) { |
636 error_info->SetReport( | 663 error_info->SetReport( |
637 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, | 664 PP_NACL_ERROR_MANIFEST_RESOLVE_URL, |
638 nacl::string("ResolveKey: no such \"files\" entry: ") + key); | 665 nacl::string("ResolveKey: no such \"files\" entry: ") + key); |
639 return false; | 666 return false; |
640 } | 667 } |
641 return GetKeyUrl(files, rest, full_url, pnacl_options, error_info); | 668 return GetKeyUrl(files, rest, full_url, pnacl_options, error_info); |
642 } | 669 } |
643 | 670 |
644 } // namespace plugin | 671 } // namespace plugin |
OLD | NEW |