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

Side by Side Diff: src/extensions/experimental/break-iterator.cc

Issue 6609038: Fix memory corruption with AdoptText method.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 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 | Annotate | Revision Log
« no previous file with comments | « src/extensions/experimental/break-iterator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 28 matching lines...) Expand all
39 icu::BreakIterator* BreakIterator::UnpackBreakIterator( 39 icu::BreakIterator* BreakIterator::UnpackBreakIterator(
40 v8::Handle<v8::Object> obj) { 40 v8::Handle<v8::Object> obj) {
41 if (break_iterator_template_->HasInstance(obj)) { 41 if (break_iterator_template_->HasInstance(obj)) {
42 return static_cast<icu::BreakIterator*>( 42 return static_cast<icu::BreakIterator*>(
43 obj->GetPointerFromInternalField(0)); 43 obj->GetPointerFromInternalField(0));
44 } 44 }
45 45
46 return NULL; 46 return NULL;
47 } 47 }
48 48
49 UnicodeString* BreakIterator::ResetAdoptedText(
50 v8::Handle<v8::Object> obj, v8::Handle<v8::Value> value) {
51 // Get the previous value from the internal field.
52 UnicodeString* text = static_cast<UnicodeString*>(
53 obj->GetPointerFromInternalField(1));
54 delete text;
55
56 // Assign new value to the internal pointer.
57 v8::String::Value text_value(value);
58 text = new UnicodeString(
59 reinterpret_cast<const UChar*>(*text_value), text_value.length());
60 obj->SetPointerInInternalField(1, text);
61
62 // Return new unicode string pointer.
63 return text;
64 }
65
49 void BreakIterator::DeleteBreakIterator(v8::Persistent<v8::Value> object, 66 void BreakIterator::DeleteBreakIterator(v8::Persistent<v8::Value> object,
50 void* param) { 67 void* param) {
51 v8::Persistent<v8::Object> persistent_object = 68 v8::Persistent<v8::Object> persistent_object =
52 v8::Persistent<v8::Object>::Cast(object); 69 v8::Persistent<v8::Object>::Cast(object);
53 70
54 // First delete the hidden C++ object. 71 // First delete the hidden C++ object.
55 // Unpacking should never return NULL here. That would only happen if 72 // Unpacking should never return NULL here. That would only happen if
56 // this method is used as the weak callback for persistent handles not 73 // this method is used as the weak callback for persistent handles not
57 // pointing to a break iterator. 74 // pointing to a break iterator.
58 delete UnpackBreakIterator(persistent_object); 75 delete UnpackBreakIterator(persistent_object);
59 76
77 delete static_cast<UnicodeString*>(
78 persistent_object->GetPointerFromInternalField(1));
79
60 // Then dispose of the persistent handle to JS object. 80 // Then dispose of the persistent handle to JS object.
61 persistent_object.Dispose(); 81 persistent_object.Dispose();
62 } 82 }
63 83
64 // Throws a JavaScript exception. 84 // Throws a JavaScript exception.
65 static v8::Handle<v8::Value> ThrowUnexpectedObjectError() { 85 static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
66 // Returns undefined, and schedules an exception to be thrown. 86 // Returns undefined, and schedules an exception to be thrown.
67 return v8::ThrowException(v8::Exception::Error( 87 return v8::ThrowException(v8::Exception::Error(
68 v8::String::New("BreakIterator method called on an object " 88 v8::String::New("BreakIterator method called on an object "
69 "that is not a BreakIterator."))); 89 "that is not a BreakIterator.")));
70 } 90 }
71 91
72 v8::Handle<v8::Value> BreakIterator::BreakIteratorAdoptText( 92 v8::Handle<v8::Value> BreakIterator::BreakIteratorAdoptText(
73 const v8::Arguments& args) { 93 const v8::Arguments& args) {
74 if (args.Length() != 1 || !args[0]->IsString()) { 94 if (args.Length() != 1 || !args[0]->IsString()) {
75 return v8::ThrowException(v8::Exception::SyntaxError( 95 return v8::ThrowException(v8::Exception::SyntaxError(
76 v8::String::New("Text input is required."))); 96 v8::String::New("Text input is required.")));
77 } 97 }
78 98
79 icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder()); 99 icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
80 if (!break_iterator) { 100 if (!break_iterator) {
81 return ThrowUnexpectedObjectError(); 101 return ThrowUnexpectedObjectError();
82 } 102 }
83 103
84 v8::String::Value text_value(args[0]); 104 break_iterator->setText(*ResetAdoptedText(args.Holder(), args[0]));
85 UnicodeString text(
86 reinterpret_cast<const UChar*>(*text_value), text_value.length());
87
88 break_iterator->setText(text);
89 105
90 return v8::Undefined(); 106 return v8::Undefined();
91 } 107 }
92 108
93 v8::Handle<v8::Value> BreakIterator::BreakIteratorFirst( 109 v8::Handle<v8::Value> BreakIterator::BreakIteratorFirst(
94 const v8::Arguments& args) { 110 const v8::Arguments& args) {
95 icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder()); 111 icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
96 if (!break_iterator) { 112 if (!break_iterator) {
97 return ThrowUnexpectedObjectError(); 113 return ThrowUnexpectedObjectError();
98 } 114 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 } 201 }
186 202
187 if (break_iterator_template_.IsEmpty()) { 203 if (break_iterator_template_.IsEmpty()) {
188 v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New()); 204 v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
189 205
190 raw_template->SetClassName(v8::String::New("v8Locale.v8BreakIterator")); 206 raw_template->SetClassName(v8::String::New("v8Locale.v8BreakIterator"));
191 207
192 // Define internal field count on instance template. 208 // Define internal field count on instance template.
193 v8::Local<v8::ObjectTemplate> object_template = 209 v8::Local<v8::ObjectTemplate> object_template =
194 raw_template->InstanceTemplate(); 210 raw_template->InstanceTemplate();
195 object_template->SetInternalFieldCount(1); 211
212 // Set aside internal fields for icu break iterator and adopted text.
213 object_template->SetInternalFieldCount(2);
196 214
197 // Define all of the prototype methods on prototype template. 215 // Define all of the prototype methods on prototype template.
198 v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate(); 216 v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
199 proto->Set(v8::String::New("adoptText"), 217 proto->Set(v8::String::New("adoptText"),
200 v8::FunctionTemplate::New(BreakIteratorAdoptText)); 218 v8::FunctionTemplate::New(BreakIteratorAdoptText));
201 proto->Set(v8::String::New("first"), 219 proto->Set(v8::String::New("first"),
202 v8::FunctionTemplate::New(BreakIteratorFirst)); 220 v8::FunctionTemplate::New(BreakIteratorFirst));
203 proto->Set(v8::String::New("next"), 221 proto->Set(v8::String::New("next"),
204 v8::FunctionTemplate::New(BreakIteratorNext)); 222 v8::FunctionTemplate::New(BreakIteratorNext));
205 proto->Set(v8::String::New("current"), 223 proto->Set(v8::String::New("current"),
206 v8::FunctionTemplate::New(BreakIteratorCurrent)); 224 v8::FunctionTemplate::New(BreakIteratorCurrent));
207 proto->Set(v8::String::New("breakType"), 225 proto->Set(v8::String::New("breakType"),
208 v8::FunctionTemplate::New(BreakIteratorBreakType)); 226 v8::FunctionTemplate::New(BreakIteratorBreakType));
209 227
210 break_iterator_template_ = 228 break_iterator_template_ =
211 v8::Persistent<v8::FunctionTemplate>::New(raw_template); 229 v8::Persistent<v8::FunctionTemplate>::New(raw_template);
212 } 230 }
213 231
214 // Create an empty object wrapper. 232 // Create an empty object wrapper.
215 v8::Local<v8::Object> local_object = 233 v8::Local<v8::Object> local_object =
216 break_iterator_template_->GetFunction()->NewInstance(); 234 break_iterator_template_->GetFunction()->NewInstance();
217 v8::Persistent<v8::Object> wrapper = 235 v8::Persistent<v8::Object> wrapper =
218 v8::Persistent<v8::Object>::New(local_object); 236 v8::Persistent<v8::Object>::New(local_object);
219 237
220 // Set break iterator as internal field of the resulting JS object. 238 // Set break iterator as internal field of the resulting JS object.
221 wrapper->SetPointerInInternalField(0, break_iterator); 239 wrapper->SetPointerInInternalField(0, break_iterator);
240 // Make sure that the pointer to adopted text is NULL.
241 wrapper->SetPointerInInternalField(1, NULL);
222 242
223 // Make object handle weak so we can delete iterator once GC kicks in. 243 // Make object handle weak so we can delete iterator once GC kicks in.
224 wrapper.MakeWeak(NULL, DeleteBreakIterator); 244 wrapper.MakeWeak(NULL, DeleteBreakIterator);
225 245
226 return wrapper; 246 return wrapper;
227 } 247 }
228 248
229 } } // namespace v8::internal 249 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/extensions/experimental/break-iterator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698