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

Side by Side Diff: lib/byte_array.cc

Issue 10782016: Enforce length/size limits for variable size heap object in order to (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 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 | « lib/array.cc ('k') | tests/vm/vm.status » ('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 Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/bootstrap_natives.h" 5 #include "vm/bootstrap_natives.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/exceptions.h" 8 #include "vm/exceptions.h"
9 #include "vm/native_entry.h" 9 #include "vm/native_entry.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 // ByteArray 14 // ByteArray
15 15
16 // Checks to see if (index * num_bytes) is in the range
17 // [0..array.ByteLength()). without the risk of integer overflow. If
18 // the index is out of range, then an IndexOutOfRangeException is thrown.
16 static void RangeCheck(const ByteArray& array, 19 static void RangeCheck(const ByteArray& array,
17 intptr_t index, 20 intptr_t index,
18 intptr_t num_bytes) { 21 intptr_t num_bytes) {
19 if (!Utils::RangeCheck(index, num_bytes, array.ByteLength())) { 22 if (!Utils::RangeCheck(index, num_bytes, array.ByteLength())) {
20 GrowableArray<const Object*> arguments; 23 const String& error = String::Handle(String::NewFormatted(
21 const Smi &index_object = Smi::Handle(Smi::New(index)); 24 "index (%ld) must be in the range [0..%ld)",
22 arguments.Add(&index_object); 25 index, (array.ByteLength() / num_bytes)));
23 Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, arguments); 26 GrowableArray<const Object*> args;
27 args.Add(&error);
28 Exceptions::ThrowByType(Exceptions::kIndexOutOfRange, args);
29 }
30 }
31
32
33 // Checks to see if a length is in the range [0..max]. If the length
34 // is out of range, then an IllegalArgumentException is thrown.
35 static void LengthCheck(intptr_t len, intptr_t max) {
36 if (len < 0 || len > max) {
37 const String& error = String::Handle(String::NewFormatted(
38 "length (%ld) must be in the range [0..%ld]", len, max));
39 GrowableArray<const Object*> args;
40 args.Add(&error);
41 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
24 } 42 }
25 } 43 }
26 44
27 45
28 #define GETTER_ARGUMENTS(ArrayT, ValueT) \ 46 #define GETTER_ARGUMENTS(ArrayT, ValueT) \
29 GET_NATIVE_ARGUMENT(ArrayT, array, arguments->At(0)); \ 47 GET_NATIVE_ARGUMENT(ArrayT, array, arguments->At(0)); \
30 GET_NATIVE_ARGUMENT(Smi, index, arguments->At(1)); 48 GET_NATIVE_ARGUMENT(Smi, index, arguments->At(1));
31 49
32 50
33 #define SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT) \ 51 #define SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT) \
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 DEFINE_NATIVE_ENTRY(ByteArray_setRange, 5) { 258 DEFINE_NATIVE_ENTRY(ByteArray_setRange, 5) {
241 ByteArray& dst = ByteArray::CheckedHandle(arguments->At(0)); 259 ByteArray& dst = ByteArray::CheckedHandle(arguments->At(0));
242 GET_NATIVE_ARGUMENT(Smi, dst_start, arguments->At(1)); 260 GET_NATIVE_ARGUMENT(Smi, dst_start, arguments->At(1));
243 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(2)); 261 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(2));
244 GET_NATIVE_ARGUMENT(ByteArray, src, arguments->At(3)); 262 GET_NATIVE_ARGUMENT(ByteArray, src, arguments->At(3));
245 GET_NATIVE_ARGUMENT(Smi, src_start, arguments->At(4)); 263 GET_NATIVE_ARGUMENT(Smi, src_start, arguments->At(4));
246 intptr_t length_value = length.Value(); 264 intptr_t length_value = length.Value();
247 intptr_t src_start_value = src_start.Value(); 265 intptr_t src_start_value = src_start.Value();
248 intptr_t dst_start_value = dst_start.Value(); 266 intptr_t dst_start_value = dst_start.Value();
249 if (length_value < 0) { 267 if (length_value < 0) {
268 const String& error = String::Handle(String::NewFormatted(
269 "length (%ld) must be non-negative", index));
250 GrowableArray<const Object*> args; 270 GrowableArray<const Object*> args;
271 args.Add(&error);
251 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); 272 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
252 } 273 }
253 RangeCheck(src, src_start_value, length_value); 274 RangeCheck(src, src_start_value, length_value);
254 RangeCheck(dst, dst_start_value, length_value); 275 RangeCheck(dst, dst_start_value, length_value);
255 ByteArray::Copy(dst, dst_start_value, src, src_start_value, length_value); 276 ByteArray::Copy(dst, dst_start_value, src, src_start_value, length_value);
256 } 277 }
257 278
258 279
259 // Int8Array 280 // Int8Array
260 281
261 DEFINE_NATIVE_ENTRY(Int8Array_new, 1) { 282 DEFINE_NATIVE_ENTRY(Int8Array_new, 1) {
262 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 283 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
263 if (length.Value() < 0) { 284 intptr_t len = length.Value();
264 GrowableArray<const Object*> args; 285 LengthCheck(len, Int8Array::kMaxElements);
265 args.Add(&length); 286 const Int8Array& new_array = Int8Array::Handle(Int8Array::New(len));
266 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
267 }
268 const Int8Array& new_array =
269 Int8Array::Handle(Int8Array::New(length.Value()));
270 arguments->SetReturn(new_array); 287 arguments->SetReturn(new_array);
271 } 288 }
272 289
273 290
274 DEFINE_NATIVE_ENTRY(Int8Array_getIndexed, 2) { 291 DEFINE_NATIVE_ENTRY(Int8Array_getIndexed, 2) {
275 GETTER(Int8Array, Smi, int8_t); 292 GETTER(Int8Array, Smi, int8_t);
276 } 293 }
277 294
278 295
279 DEFINE_NATIVE_ENTRY(Int8Array_setIndexed, 3) { 296 DEFINE_NATIVE_ENTRY(Int8Array_setIndexed, 3) {
280 SETTER(Int8Array, Smi, Value, int8_t); 297 SETTER(Int8Array, Smi, Value, int8_t);
281 } 298 }
282 299
283 300
284 // Uint8Array 301 // Uint8Array
285 302
286 DEFINE_NATIVE_ENTRY(Uint8Array_new, 1) { 303 DEFINE_NATIVE_ENTRY(Uint8Array_new, 1) {
287 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 304 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
288 if (length.Value() < 0) { 305 intptr_t len = length.Value();
289 GrowableArray<const Object*> args; 306 LengthCheck(len, Uint8Array::kMaxElements);
290 args.Add(&length); 307 const Uint8Array& new_array = Uint8Array::Handle(Uint8Array::New(len));
291 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
292 }
293 const Uint8Array& new_array =
294 Uint8Array::Handle(Uint8Array::New(length.Value()));
295 arguments->SetReturn(new_array); 308 arguments->SetReturn(new_array);
296 } 309 }
297 310
298 311
299 DEFINE_NATIVE_ENTRY(Uint8Array_getIndexed, 2) { 312 DEFINE_NATIVE_ENTRY(Uint8Array_getIndexed, 2) {
300 GETTER(Uint8Array, Smi, uint8_t); 313 GETTER(Uint8Array, Smi, uint8_t);
301 } 314 }
302 315
303 316
304 DEFINE_NATIVE_ENTRY(Uint8Array_setIndexed, 3) { 317 DEFINE_NATIVE_ENTRY(Uint8Array_setIndexed, 3) {
305 SETTER(Uint8Array, Smi, Value, uint8_t); 318 SETTER(Uint8Array, Smi, Value, uint8_t);
306 } 319 }
307 320
308 321
309 // Int16Array 322 // Int16Array
310 323
311 DEFINE_NATIVE_ENTRY(Int16Array_new, 1) { 324 DEFINE_NATIVE_ENTRY(Int16Array_new, 1) {
312 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 325 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
313 if (length.Value() < 0) { 326 intptr_t len = length.Value();
314 GrowableArray<const Object*> args; 327 LengthCheck(len, Int16Array::kMaxElements);
315 args.Add(&length); 328 const Int16Array& new_array = Int16Array::Handle(Int16Array::New(len));
316 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
317 }
318 const Int16Array& new_array =
319 Int16Array::Handle(Int16Array::New(length.Value()));
320 arguments->SetReturn(new_array); 329 arguments->SetReturn(new_array);
321 } 330 }
322 331
323 332
324 DEFINE_NATIVE_ENTRY(Int16Array_getIndexed, 2) { 333 DEFINE_NATIVE_ENTRY(Int16Array_getIndexed, 2) {
325 GETTER(Int16Array, Smi, int16_t); 334 GETTER(Int16Array, Smi, int16_t);
326 } 335 }
327 336
328 337
329 DEFINE_NATIVE_ENTRY(Int16Array_setIndexed, 3) { 338 DEFINE_NATIVE_ENTRY(Int16Array_setIndexed, 3) {
330 SETTER(Int16Array, Smi, Value, int16_t); 339 SETTER(Int16Array, Smi, Value, int16_t);
331 } 340 }
332 341
333 342
334 // Uint16Array 343 // Uint16Array
335 344
336 DEFINE_NATIVE_ENTRY(Uint16Array_new, 1) { 345 DEFINE_NATIVE_ENTRY(Uint16Array_new, 1) {
337 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 346 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
338 if (length.Value() < 0) { 347 intptr_t len = length.Value();
339 GrowableArray<const Object*> args; 348 LengthCheck(len, Uint16Array::kMaxElements);
340 args.Add(&length); 349 const Uint16Array& new_array = Uint16Array::Handle(Uint16Array::New(len));
341 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
342 }
343 const Uint16Array& new_array =
344 Uint16Array::Handle(Uint16Array::New(length.Value()));
345 arguments->SetReturn(new_array); 350 arguments->SetReturn(new_array);
346 } 351 }
347 352
348 353
349 DEFINE_NATIVE_ENTRY(Uint16Array_getIndexed, 2) { 354 DEFINE_NATIVE_ENTRY(Uint16Array_getIndexed, 2) {
350 GETTER(Uint16Array, Smi, uint16_t); 355 GETTER(Uint16Array, Smi, uint16_t);
351 } 356 }
352 357
353 358
354 DEFINE_NATIVE_ENTRY(Uint16Array_setIndexed, 3) { 359 DEFINE_NATIVE_ENTRY(Uint16Array_setIndexed, 3) {
355 SETTER(Uint16Array, Smi, Value, uint16_t); 360 SETTER(Uint16Array, Smi, Value, uint16_t);
356 } 361 }
357 362
358 363
359 // Int32Array 364 // Int32Array
360 365
361 DEFINE_NATIVE_ENTRY(Int32Array_new, 1) { 366 DEFINE_NATIVE_ENTRY(Int32Array_new, 1) {
362 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 367 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
363 if (length.Value() < 0) { 368 intptr_t len = length.Value();
364 GrowableArray<const Object*> args; 369 LengthCheck(len, Int32Array::kMaxElements);
365 args.Add(&length); 370 const Int32Array& new_array = Int32Array::Handle(Int32Array::New(len));
366 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
367 }
368 const Int32Array& new_array =
369 Int32Array::Handle(Int32Array::New(length.Value()));
370 arguments->SetReturn(new_array); 371 arguments->SetReturn(new_array);
371 } 372 }
372 373
373 374
374 DEFINE_NATIVE_ENTRY(Int32Array_getIndexed, 2) { 375 DEFINE_NATIVE_ENTRY(Int32Array_getIndexed, 2) {
375 GETTER(Int32Array, Integer, int32_t); 376 GETTER(Int32Array, Integer, int32_t);
376 } 377 }
377 378
378 379
379 DEFINE_NATIVE_ENTRY(Int32Array_setIndexed, 3) { 380 DEFINE_NATIVE_ENTRY(Int32Array_setIndexed, 3) {
380 SETTER(Int32Array, Integer, AsInt64Value, int32_t); 381 SETTER(Int32Array, Integer, AsInt64Value, int32_t);
381 } 382 }
382 383
383 384
384 // Uint32Array 385 // Uint32Array
385 386
386 DEFINE_NATIVE_ENTRY(Uint32Array_new, 1) { 387 DEFINE_NATIVE_ENTRY(Uint32Array_new, 1) {
387 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 388 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
388 if (length.Value() < 0) { 389 intptr_t len = length.Value();
389 GrowableArray<const Object*> args; 390 LengthCheck(len, Uint32Array::kMaxElements);
390 args.Add(&length); 391 const Uint32Array& new_array = Uint32Array::Handle(Uint32Array::New(len));
391 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
392 }
393 const Uint32Array& new_array =
394 Uint32Array::Handle(Uint32Array::New(length.Value()));
395 arguments->SetReturn(new_array); 392 arguments->SetReturn(new_array);
396 } 393 }
397 394
398 395
399 DEFINE_NATIVE_ENTRY(Uint32Array_getIndexed, 2) { 396 DEFINE_NATIVE_ENTRY(Uint32Array_getIndexed, 2) {
400 GETTER(Uint32Array, Integer, uint32_t); 397 GETTER(Uint32Array, Integer, uint32_t);
401 } 398 }
402 399
403 400
404 DEFINE_NATIVE_ENTRY(Uint32Array_setIndexed, 3) { 401 DEFINE_NATIVE_ENTRY(Uint32Array_setIndexed, 3) {
405 SETTER(Uint32Array, Integer, AsInt64Value, uint32_t); 402 SETTER(Uint32Array, Integer, AsInt64Value, uint32_t);
406 } 403 }
407 404
408 405
409 // Int64Array 406 // Int64Array
410 407
411 DEFINE_NATIVE_ENTRY(Int64Array_new, 1) { 408 DEFINE_NATIVE_ENTRY(Int64Array_new, 1) {
412 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 409 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
413 if (length.Value() < 0) { 410 intptr_t len = length.Value();
414 GrowableArray<const Object*> args; 411 LengthCheck(len, Int64Array::kMaxElements);
415 args.Add(&length); 412 const Int64Array& new_array = Int64Array::Handle(Int64Array::New(len));
416 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
417 }
418 const Int64Array& new_array =
419 Int64Array::Handle(Int64Array::New(length.Value()));
420 arguments->SetReturn(new_array); 413 arguments->SetReturn(new_array);
421 } 414 }
422 415
423 416
424 DEFINE_NATIVE_ENTRY(Int64Array_getIndexed, 2) { 417 DEFINE_NATIVE_ENTRY(Int64Array_getIndexed, 2) {
425 GETTER(Int64Array, Integer, int64_t); 418 GETTER(Int64Array, Integer, int64_t);
426 } 419 }
427 420
428 421
429 DEFINE_NATIVE_ENTRY(Int64Array_setIndexed, 3) { 422 DEFINE_NATIVE_ENTRY(Int64Array_setIndexed, 3) {
430 SETTER(Int64Array, Integer, AsInt64Value, int64_t); 423 SETTER(Int64Array, Integer, AsInt64Value, int64_t);
431 } 424 }
432 425
433 426
434 // Uint64Array 427 // Uint64Array
435 428
436 DEFINE_NATIVE_ENTRY(Uint64Array_new, 1) { 429 DEFINE_NATIVE_ENTRY(Uint64Array_new, 1) {
437 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 430 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
438 if (length.Value() < 0) { 431 intptr_t len = length.Value();
439 GrowableArray<const Object*> args; 432 LengthCheck(len, Uint64Array::kMaxElements);
440 args.Add(&length); 433 const Uint64Array& new_array = Uint64Array::Handle(Uint64Array::New(len));
441 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
442 }
443 const Uint64Array& new_array =
444 Uint64Array::Handle(Uint64Array::New(length.Value()));
445 arguments->SetReturn(new_array); 434 arguments->SetReturn(new_array);
446 } 435 }
447 436
448 437
449 DEFINE_NATIVE_ENTRY(Uint64Array_getIndexed, 2) { 438 DEFINE_NATIVE_ENTRY(Uint64Array_getIndexed, 2) {
450 GETTER_UINT64(Uint64Array); 439 GETTER_UINT64(Uint64Array);
451 } 440 }
452 441
453 442
454 DEFINE_NATIVE_ENTRY(Uint64Array_setIndexed, 3) { 443 DEFINE_NATIVE_ENTRY(Uint64Array_setIndexed, 3) {
455 SETTER_UINT64(Uint64Array); 444 SETTER_UINT64(Uint64Array);
456 } 445 }
457 446
458 447
459 // Float32Array 448 // Float32Array
460 449
461 DEFINE_NATIVE_ENTRY(Float32Array_new, 1) { 450 DEFINE_NATIVE_ENTRY(Float32Array_new, 1) {
462 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 451 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
463 if (length.Value() < 0) { 452 intptr_t len = length.Value();
464 GrowableArray<const Object*> args; 453 LengthCheck(len, Float32Array::kMaxElements);
465 args.Add(&length); 454 const Float32Array& new_array = Float32Array::Handle(Float32Array::New(len));
466 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
467 }
468 const Float32Array& new_array =
469 Float32Array::Handle(Float32Array::New(length.Value()));
470 arguments->SetReturn(new_array); 455 arguments->SetReturn(new_array);
471 } 456 }
472 457
473 458
474 DEFINE_NATIVE_ENTRY(Float32Array_getIndexed, 2) { 459 DEFINE_NATIVE_ENTRY(Float32Array_getIndexed, 2) {
475 GETTER(Float32Array, Double, float); 460 GETTER(Float32Array, Double, float);
476 } 461 }
477 462
478 463
479 DEFINE_NATIVE_ENTRY(Float32Array_setIndexed, 3) { 464 DEFINE_NATIVE_ENTRY(Float32Array_setIndexed, 3) {
480 SETTER(Float32Array, Double, value, float); 465 SETTER(Float32Array, Double, value, float);
481 } 466 }
482 467
483 468
484 // Float64Array 469 // Float64Array
485 470
486 DEFINE_NATIVE_ENTRY(Float64Array_new, 1) { 471 DEFINE_NATIVE_ENTRY(Float64Array_new, 1) {
487 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0)); 472 GET_NATIVE_ARGUMENT(Smi, length, arguments->At(0));
488 if (length.Value() < 0) { 473 intptr_t len = length.Value();
489 GrowableArray<const Object*> args; 474 LengthCheck(len, Float64Array::kMaxElements);
490 args.Add(&length); 475 const Float64Array& new_array = Float64Array::Handle(Float64Array::New(len));
491 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
492 }
493 const Float64Array& new_array =
494 Float64Array::Handle(Float64Array::New(length.Value()));
495 arguments->SetReturn(new_array); 476 arguments->SetReturn(new_array);
496 } 477 }
497 478
498 479
499 DEFINE_NATIVE_ENTRY(Float64Array_getIndexed, 2) { 480 DEFINE_NATIVE_ENTRY(Float64Array_getIndexed, 2) {
500 GETTER(Float64Array, Double, double); 481 GETTER(Float64Array, Double, double);
501 } 482 }
502 483
503 484
504 DEFINE_NATIVE_ENTRY(Float64Array_setIndexed, 3) { 485 DEFINE_NATIVE_ENTRY(Float64Array_setIndexed, 3) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_getIndexed, 2) { 600 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_getIndexed, 2) {
620 GETTER(ExternalFloat64Array, Double, double); 601 GETTER(ExternalFloat64Array, Double, double);
621 } 602 }
622 603
623 604
624 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_setIndexed, 3) { 605 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_setIndexed, 3) {
625 SETTER(ExternalFloat64Array, Double, value, double); 606 SETTER(ExternalFloat64Array, Double, value, double);
626 } 607 }
627 608
628 } // namespace dart 609 } // namespace dart
OLDNEW
« no previous file with comments | « lib/array.cc ('k') | tests/vm/vm.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698