Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(159510)

Delta Between Two Patch Sets: Objects/sliceobject.c

Issue 14794: slice.indices raises OverflowError
Left Patch Set: Created 7 years, 1 month ago
Right Patch Set: Created 7 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_slice.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 Written by Jim Hugunin and Chris Chase. 2 Written by Jim Hugunin and Chris Chase.
3 3
4 This includes both the singular ellipsis object and slice objects. 4 This includes both the singular ellipsis object and slice objects.
5 5
6 Guido, feel free to do whatever you want in the way of copyrights 6 Guido, feel free to do whatever you want in the way of copyrights
7 for this file. 7 for this file.
8 */ 8 */
9 9
10 /* 10 /*
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step) ; 292 return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step) ;
293 } 293 }
294 294
295 static PyMemberDef slice_members[] = { 295 static PyMemberDef slice_members[] = {
296 {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, 296 {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
297 {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, 297 {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
298 {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, 298 {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
299 {0} 299 {0}
300 }; 300 };
301 301
302 /* Helper function to convert a slice argument to a PyLong, and raise TypeError
303 with a suitable message on failure. */
304
305 static PyObject*
306 evaluate_slice_index(PyObject *v)
307 {
308 if (PyIndex_Check(v)) {
storchaka 2012/11/04 12:29:34 Why not EAFP? PyObject *index = PyNumber_Index(v)
309 return PyNumber_Index(v);
310 }
311 else {
312 PyErr_SetString(PyExc_TypeError,
313 "slice indices must be integers or "
314 "None or have an __index__ method");
315 return NULL;
316 }
317 }
318
319 /* Implementation of slice.indices. */
320
302 static PyObject* 321 static PyObject*
303 slice_indices(PySliceObject* self, PyObject* len) 322 slice_indices(PySliceObject* self, PyObject* len)
304 { 323 {
305 PyObject *start=NULL, *stop=NULL, *step=NULL; 324 PyObject *start=NULL, *stop=NULL, *step=NULL;
306 PyObject *length=NULL, *upper=NULL, *lower=NULL, *zero=NULL; 325 PyObject *length=NULL, *upper=NULL, *lower=NULL, *zero=NULL;
307 int step_is_negative, stop_is_negative, start_is_negative; 326 int step_is_negative, cmp;
308 int length_is_negative, step_is_zero;
309 327
310 zero = PyLong_FromLong(0L); 328 zero = PyLong_FromLong(0L);
311 if (zero == NULL) 329 if (zero == NULL)
312 return NULL; 330 return NULL;
313 331
314 /* Compute step and length as integers. */ 332 /* Compute step and length as integers. */
315 length = PyNumber_Index(len); 333 length = PyNumber_Index(len);
316 if (length == NULL) 334 if (length == NULL)
317 goto error; 335 goto error;
318 336
319 if (self->step == Py_None) 337 if (self->step == Py_None)
320 step = PyLong_FromLong(1L); 338 step = PyLong_FromLong(1L);
321 else 339 else
322 step = PyNumber_Index(self->step); 340 step = evaluate_slice_index(self->step);
323 if (step == NULL) 341 if (step == NULL)
324 goto error; 342 goto error;
325 343
326 /* Raise ValueError for negative length or zero step. */ 344 /* Raise ValueError for negative length or zero step. */
327 length_is_negative = PyObject_RichCompareBool(length, zero, Py_LT); 345 cmp = PyObject_RichCompareBool(length, zero, Py_LT);
328 if (length_is_negative < 0) { 346 if (cmp < 0) {
329 goto error; 347 goto error;
330 } 348 }
331 if (length_is_negative) { 349 if (cmp) {
332 PyErr_SetString(PyExc_ValueError, 350 PyErr_SetString(PyExc_ValueError,
333 "length should not be negative"); 351 "length should not be negative");
334 goto error; 352 goto error;
335 } 353 }
336 354
337 step_is_zero = PyObject_RichCompareBool(step, zero, Py_EQ); 355 cmp = PyObject_RichCompareBool(step, zero, Py_EQ);
338 if (step_is_zero < 0) { 356 if (cmp < 0) {
339 goto error; 357 goto error;
340 } 358 }
341 if (step_is_zero) { 359 if (cmp) {
342 PyErr_SetString(PyExc_ValueError, 360 PyErr_SetString(PyExc_ValueError,
343 "slice step cannot be zero"); 361 "slice step cannot be zero");
344 goto error; 362 goto error;
345 } 363 }
346 364
347 /* Find lower and upper bounds for start and stop. */ 365 /* Find lower and upper bounds for start and stop. */
348 step_is_negative = PyObject_RichCompareBool(step, zero, Py_LT); 366 step_is_negative = PyObject_RichCompareBool(step, zero, Py_LT);
349 if (step_is_negative < 0) { 367 if (step_is_negative < 0) {
350 goto error; 368 goto error;
351 } 369 }
(...skipping 12 matching lines...) Expand all
364 upper = length; 382 upper = length;
365 Py_INCREF(upper); 383 Py_INCREF(upper);
366 } 384 }
367 385
368 /* Compute start. */ 386 /* Compute start. */
369 if (self->start == Py_None) { 387 if (self->start == Py_None) {
370 start = step_is_negative ? upper : lower; 388 start = step_is_negative ? upper : lower;
371 Py_INCREF(start); 389 Py_INCREF(start);
372 } 390 }
373 else { 391 else {
374 PyObject *start_as_integer = PyNumber_Index(self->start); 392 start = evaluate_slice_index(self->start);
375 if (start_as_integer == NULL) 393 if (start == NULL)
376 goto error; 394 goto error;
377 395
378 start_is_negative = PyObject_RichCompareBool(start_as_integer, 396 cmp = PyObject_RichCompareBool(start, zero, Py_LT);
379 zero, Py_LT); 397 if (cmp < 0)
380 if (start_is_negative < 0) {
381 Py_DECREF(start_as_integer);
382 goto error; 398 goto error;
383 } 399 if (cmp) {
384 if (start_is_negative) { 400 /* start += length */
385 int start_is_low; 401 PyObject *tmp = PyNumber_Add(start, length);
386 /* start_as_integer += length */ 402 Py_DECREF(start);
387 PyObject *tmp = PyNumber_Add(start_as_integer, length); 403 start = tmp;
388 Py_DECREF(start_as_integer); 404 if (start == NULL)
389 start_as_integer = tmp;
390 if (start_as_integer == NULL)
391 goto error; 405 goto error;
392 406
393 start_is_low = PyObject_RichCompareBool(start_as_integer, 407 cmp = PyObject_RichCompareBool(start, lower, Py_LT);
394 lower, Py_LE); 408 if (cmp < 0)
395 if (start_is_low < 0)
396 goto error; 409 goto error;
397 if (start_is_low) 410 if (cmp) {
411 Py_INCREF(lower);
412 Py_DECREF(start);
398 start = lower; 413 start = lower;
399 else 414 }
400 start = start_as_integer;
401 } 415 }
402 else { 416 else {
403 int start_is_high = PyObject_RichCompareBool(start_as_integer, 417 cmp = PyObject_RichCompareBool(start, upper, Py_GT);
404 upper, Py_GE); 418 if (cmp < 0)
405 if (start_is_high < 0)
406 goto error; 419 goto error;
407 if (start_is_high) 420 if (cmp) {
421 Py_INCREF(upper);
422 Py_DECREF(start);
408 start = upper; 423 start = upper;
409 else 424 }
410 start = start_as_integer;
411 } 425 }
412 Py_INCREF(start);
413 Py_DECREF(start_as_integer);
414 } 426 }
415 427
416 /* Compute stop. */ 428 /* Compute stop. */
417 if (self->stop == Py_None) { 429 if (self->stop == Py_None) {
418 stop = step_is_negative ? lower : upper; 430 stop = step_is_negative ? lower : upper;
419 Py_INCREF(stop); 431 Py_INCREF(stop);
420 } 432 }
421 else { 433 else {
422 PyObject *stop_as_integer = PyNumber_Index(self->stop); 434 stop = evaluate_slice_index(self->stop);
423 if (stop_as_integer == NULL) 435 if (stop == NULL)
424 goto error; 436 goto error;
425 437
426 stop_is_negative = PyObject_RichCompareBool(stop_as_integer, 438 cmp = PyObject_RichCompareBool(stop, zero, Py_LT);
427 zero, Py_LT); 439 if (cmp < 0)
428 if (stop_is_negative < 0) {
429 Py_DECREF(stop_as_integer);
430 goto error; 440 goto error;
431 } 441 if (cmp) {
432 if (stop_is_negative) { 442 /* stop += length */
433 int stop_is_low; 443 PyObject *tmp = PyNumber_Add(stop, length);
434 /* stop_as_integer += length */ 444 Py_DECREF(stop);
435 PyObject *tmp = PyNumber_Add(stop_as_integer, length); 445 stop = tmp;
436 Py_DECREF(stop_as_integer); 446 if (stop == NULL)
437 stop_as_integer = tmp;
438 if (stop_as_integer == NULL)
439 goto error; 447 goto error;
440 448
441 stop_is_low = PyObject_RichCompareBool(stop_as_integer, 449 cmp = PyObject_RichCompareBool(stop, lower, Py_LT);
442 lower, Py_LE); 450 if (cmp < 0)
443 if (stop_is_low < 0)
444 goto error; 451 goto error;
445 if (stop_is_low) 452 if (cmp) {
453 Py_INCREF(lower);
454 Py_DECREF(stop);
446 stop = lower; 455 stop = lower;
447 else 456 }
448 stop = stop_as_integer;
449 } 457 }
450 else { 458 else {
451 int stop_is_high = PyObject_RichCompareBool(stop_as_integer, 459 cmp = PyObject_RichCompareBool(stop, upper, Py_GT);
452 upper, Py_GE); 460 if (cmp < 0)
453 if (stop_is_high < 0)
454 goto error; 461 goto error;
455 if (stop_is_high) 462 if (cmp) {
463 Py_INCREF(upper);
464 Py_DECREF(stop);
456 stop = upper; 465 stop = upper;
457 else 466 }
458 stop = stop_as_integer;
459 } 467 }
460 Py_INCREF(stop); 468 }
461 Py_DECREF(stop_as_integer); 469
462 }
463 Py_DECREF(upper); 470 Py_DECREF(upper);
464 Py_DECREF(lower); 471 Py_DECREF(lower);
465 Py_DECREF(length); 472 Py_DECREF(length);
466 Py_DECREF(zero); 473 Py_DECREF(zero);
467 return Py_BuildValue("(NNN)", start, stop, step); 474 return Py_BuildValue("(NNN)", start, stop, step);
468 475
469 error: 476 error:
470 Py_XDECREF(start); 477 Py_XDECREF(start);
471 Py_XDECREF(stop); 478 Py_XDECREF(stop);
472 Py_XDECREF(step); 479 Py_XDECREF(step);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 0, /* tp_getset */ 600 0, /* tp_getset */
594 0, /* tp_base */ 601 0, /* tp_base */
595 0, /* tp_dict */ 602 0, /* tp_dict */
596 0, /* tp_descr_get */ 603 0, /* tp_descr_get */
597 0, /* tp_descr_set */ 604 0, /* tp_descr_set */
598 0, /* tp_dictoffset */ 605 0, /* tp_dictoffset */
599 0, /* tp_init */ 606 0, /* tp_init */
600 0, /* tp_alloc */ 607 0, /* tp_alloc */
601 slice_new, /* tp_new */ 608 slice_new, /* tp_new */
602 }; 609 };
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+