Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(697)

Side by Side Diff: base/values.cc

Issue 2750533003: Temporarily CHECK use after free in Value (Closed)
Patch Set: Fix more Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/values.h ('k') | chrome/browser/ui/cocoa/applescript/apple_event_util.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/values.h" 5 #include "base/values.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 return; 117 return;
118 case Type::BINARY: 118 case Type::BINARY:
119 binary_value_.Init(); 119 binary_value_.Init();
120 return; 120 return;
121 case Type::DICTIONARY: 121 case Type::DICTIONARY:
122 dict_ptr_.Init(MakeUnique<DictStorage>()); 122 dict_ptr_.Init(MakeUnique<DictStorage>());
123 return; 123 return;
124 case Type::LIST: 124 case Type::LIST:
125 list_.Init(); 125 list_.Init();
126 return; 126 return;
127 case Type::DELETED:
128 // TODO(crbug.com/697817): Remove.
129 CHECK(false);
130 return;
127 } 131 }
128 } 132 }
129 133
130 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} 134 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
131 135
132 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} 136 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
133 137
134 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { 138 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
135 if (!std::isfinite(double_value_)) { 139 if (!std::isfinite(double_value_)) {
136 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " 140 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 InternalCleanup(); 197 InternalCleanup();
194 InternalMoveConstructFrom(std::move(that)); 198 InternalMoveConstructFrom(std::move(that));
195 } 199 }
196 } 200 }
197 201
198 return *this; 202 return *this;
199 } 203 }
200 204
201 Value::~Value() { 205 Value::~Value() {
202 InternalCleanup(); 206 InternalCleanup();
207 type_ = Type::DELETED;
203 } 208 }
204 209
205 // static 210 // static
206 const char* Value::GetTypeName(Value::Type type) { 211 const char* Value::GetTypeName(Value::Type type) {
207 DCHECK_GE(static_cast<int>(type), 0); 212 DCHECK_GE(static_cast<int>(type), 0);
208 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); 213 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
209 return kTypeNames[static_cast<size_t>(type)]; 214 return kTypeNames[static_cast<size_t>(type)];
210 } 215 }
211 216
212 bool Value::GetBool() const { 217 bool Value::GetBool() const {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 if (list_->size() != other->list_->size()) 440 if (list_->size() != other->list_->size())
436 return false; 441 return false;
437 442
438 return std::equal(std::begin(*list_), std::end(*list_), 443 return std::equal(std::begin(*list_), std::end(*list_),
439 std::begin(*(other->list_)), 444 std::begin(*(other->list_)),
440 [](const ListStorage::value_type& lhs, 445 [](const ListStorage::value_type& lhs,
441 const ListStorage::value_type& rhs) { 446 const ListStorage::value_type& rhs) {
442 return lhs->Equals(rhs.get()); 447 return lhs->Equals(rhs.get());
443 }); 448 });
444 } 449 }
450 case Type::DELETED:
451 // TODO(crbug.com/697817): This means a use-after-free.
452 CHECK(false);
453 return false;
445 } 454 }
446 455
447 NOTREACHED(); 456 NOTREACHED();
448 return false; 457 return false;
449 } 458 }
450 459
451 // static 460 // static
452 bool Value::Equals(const Value* a, const Value* b) { 461 bool Value::Equals(const Value* a, const Value* b) {
453 if ((a == NULL) && (b == NULL)) return true; 462 if ((a == NULL) && (b == NULL)) return true;
454 if ((a == NULL) ^ (b == NULL)) return false; 463 if ((a == NULL) ^ (b == NULL)) return false;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 // DictStorage and ListStorage are move-only types due to the presence of 505 // DictStorage and ListStorage are move-only types due to the presence of
497 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 506 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here.
498 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 507 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
499 // can be copied directly. 508 // can be copied directly.
500 case Type::DICTIONARY: 509 case Type::DICTIONARY:
501 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); 510 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_));
502 return; 511 return;
503 case Type::LIST: 512 case Type::LIST:
504 list_.Init(std::move(*that.CreateDeepCopy()->list_)); 513 list_.Init(std::move(*that.CreateDeepCopy()->list_));
505 return; 514 return;
515 case Type::DELETED:
516 // TODO(crbug.com/697817): This means |that| is used after free.
517 CHECK(false);
518 return;
506 } 519 }
507 } 520 }
508 521
509 void Value::InternalMoveConstructFrom(Value&& that) { 522 void Value::InternalMoveConstructFrom(Value&& that) {
510 type_ = that.type_; 523 type_ = that.type_;
511 524
512 switch (type_) { 525 switch (type_) {
513 case Type::NONE: 526 case Type::NONE:
514 case Type::BOOLEAN: 527 case Type::BOOLEAN:
515 case Type::INTEGER: 528 case Type::INTEGER:
516 case Type::DOUBLE: 529 case Type::DOUBLE:
517 InternalCopyFundamentalValue(that); 530 InternalCopyFundamentalValue(that);
518 return; 531 return;
519 532
520 case Type::STRING: 533 case Type::STRING:
521 string_value_.InitFromMove(std::move(that.string_value_)); 534 string_value_.InitFromMove(std::move(that.string_value_));
522 return; 535 return;
523 case Type::BINARY: 536 case Type::BINARY:
524 binary_value_.InitFromMove(std::move(that.binary_value_)); 537 binary_value_.InitFromMove(std::move(that.binary_value_));
525 return; 538 return;
526 case Type::DICTIONARY: 539 case Type::DICTIONARY:
527 dict_ptr_.InitFromMove(std::move(that.dict_ptr_)); 540 dict_ptr_.InitFromMove(std::move(that.dict_ptr_));
528 return; 541 return;
529 case Type::LIST: 542 case Type::LIST:
530 list_.InitFromMove(std::move(that.list_)); 543 list_.InitFromMove(std::move(that.list_));
531 return; 544 return;
545 case Type::DELETED:
546 // TODO(crbug.com/697817): This means |that| is used after free.
547 CHECK(false);
548 return;
532 } 549 }
533 } 550 }
534 551
535 void Value::InternalCopyAssignFromSameType(const Value& that) { 552 void Value::InternalCopyAssignFromSameType(const Value& that) {
536 CHECK_EQ(type_, that.type_); 553 CHECK_EQ(type_, that.type_);
537 554
538 switch (type_) { 555 switch (type_) {
539 case Type::NONE: 556 case Type::NONE:
540 case Type::BOOLEAN: 557 case Type::BOOLEAN:
541 case Type::INTEGER: 558 case Type::INTEGER:
(...skipping 10 matching lines...) Expand all
552 // DictStorage and ListStorage are move-only types due to the presence of 569 // DictStorage and ListStorage are move-only types due to the presence of
553 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. 570 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here.
554 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage 571 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
555 // can be copied directly. 572 // can be copied directly.
556 case Type::DICTIONARY: 573 case Type::DICTIONARY:
557 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); 574 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_);
558 return; 575 return;
559 case Type::LIST: 576 case Type::LIST:
560 *list_ = std::move(*that.CreateDeepCopy()->list_); 577 *list_ = std::move(*that.CreateDeepCopy()->list_);
561 return; 578 return;
579 case Type::DELETED:
580 // TODO(crbug.com/697817): This means |that| is used after free.
581 CHECK(false);
582 return;
562 } 583 }
563 } 584 }
564 585
565 void Value::InternalMoveAssignFromSameType(Value&& that) { 586 void Value::InternalMoveAssignFromSameType(Value&& that) {
566 CHECK_EQ(type_, that.type_); 587 CHECK_EQ(type_, that.type_);
567 588
568 switch (type_) { 589 switch (type_) {
569 case Type::NONE: 590 case Type::NONE:
570 case Type::BOOLEAN: 591 case Type::BOOLEAN:
571 case Type::INTEGER: 592 case Type::INTEGER:
572 case Type::DOUBLE: 593 case Type::DOUBLE:
573 InternalCopyFundamentalValue(that); 594 InternalCopyFundamentalValue(that);
574 return; 595 return;
575 596
576 case Type::STRING: 597 case Type::STRING:
577 *string_value_ = std::move(*that.string_value_); 598 *string_value_ = std::move(*that.string_value_);
578 return; 599 return;
579 case Type::BINARY: 600 case Type::BINARY:
580 *binary_value_ = std::move(*that.binary_value_); 601 *binary_value_ = std::move(*that.binary_value_);
581 return; 602 return;
582 case Type::DICTIONARY: 603 case Type::DICTIONARY:
583 *dict_ptr_ = std::move(*that.dict_ptr_); 604 *dict_ptr_ = std::move(*that.dict_ptr_);
584 return; 605 return;
585 case Type::LIST: 606 case Type::LIST:
586 *list_ = std::move(*that.list_); 607 *list_ = std::move(*that.list_);
587 return; 608 return;
609 case Type::DELETED:
610 // TODO(crbug.com/697817): This means |that| is used after free.
611 CHECK(false);
612 return;
588 } 613 }
589 } 614 }
590 615
591 void Value::InternalCleanup() { 616 void Value::InternalCleanup() {
592 switch (type_) { 617 switch (type_) {
593 case Type::NONE: 618 case Type::NONE:
594 case Type::BOOLEAN: 619 case Type::BOOLEAN:
595 case Type::INTEGER: 620 case Type::INTEGER:
596 case Type::DOUBLE: 621 case Type::DOUBLE:
597 // Nothing to do 622 // Nothing to do
598 return; 623 return;
599 624
600 case Type::STRING: 625 case Type::STRING:
601 string_value_.Destroy(); 626 string_value_.Destroy();
602 return; 627 return;
603 case Type::BINARY: 628 case Type::BINARY:
604 binary_value_.Destroy(); 629 binary_value_.Destroy();
605 return; 630 return;
606 case Type::DICTIONARY: 631 case Type::DICTIONARY:
607 dict_ptr_.Destroy(); 632 dict_ptr_.Destroy();
608 return; 633 return;
609 case Type::LIST: 634 case Type::LIST:
610 list_.Destroy(); 635 list_.Destroy();
611 return; 636 return;
637 case Type::DELETED:
638 // TODO(crbug.com/697817): This means a use-after-free.
639 CHECK(false);
640 return;
612 } 641 }
613 } 642 }
614 643
615 ///////////////////// DictionaryValue //////////////////// 644 ///////////////////// DictionaryValue ////////////////////
616 645
617 // static 646 // static
618 std::unique_ptr<DictionaryValue> DictionaryValue::From( 647 std::unique_ptr<DictionaryValue> DictionaryValue::From(
619 std::unique_ptr<Value> value) { 648 std::unique_ptr<Value> value) {
620 DictionaryValue* out; 649 DictionaryValue* out;
621 if (value && value->GetAsDictionary(&out)) { 650 if (value && value->GetAsDictionary(&out)) {
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 } 1384 }
1356 1385
1357 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1386 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1358 if (static_cast<int>(type) < 0 || 1387 if (static_cast<int>(type) < 0 ||
1359 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1388 static_cast<size_t>(type) >= arraysize(kTypeNames))
1360 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1389 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1361 return out << Value::GetTypeName(type); 1390 return out << Value::GetTypeName(type);
1362 } 1391 }
1363 1392
1364 } // namespace base 1393 } // namespace base
OLDNEW
« no previous file with comments | « base/values.h ('k') | chrome/browser/ui/cocoa/applescript/apple_event_util.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698