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

Side by Side Diff: Objects/sliceobject.c

Issue 14794: slice.indices raises OverflowError
Patch Set: Created 6 years, 8 months 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:
View unified diff | Download patch
« no previous file with comments | « Lib/test/test_slice.py ('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 /* 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 static PyObject* 302 static PyObject*
303 slice_indices(PySliceObject* self, PyObject* len) 303 slice_indices(PySliceObject* self, PyObject* len)
304 { 304 {
305 Py_ssize_t ilen, start, stop, step, slicelength; 305 PyObject *start=NULL, *stop=NULL, *step=NULL;
306 PyObject *length=NULL, *upper=NULL, *lower=NULL, *zero=NULL;
307 int step_is_negative, cmp;
306 308
307 ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); 309 zero = PyLong_FromLong(0L);
310 if (zero == NULL)
311 return NULL;
308 312
309 if (ilen == -1 && PyErr_Occurred()) { 313 /* Compute step and length as integers. */
310 return NULL; 314 length = PyNumber_Index(len);
315 if (length == NULL)
316 goto error;
317
318 if (self->step == Py_None)
319 step = PyLong_FromLong(1L);
320 else
321 step = PyNumber_Index(self->step);
322 if (step == NULL)
323 goto error;
324
325 /* Raise ValueError for negative length or zero step. */
326 cmp = PyObject_RichCompareBool(length, zero, Py_LT);
327 if (cmp < 0) {
328 goto error;
329 }
330 if (cmp) {
331 PyErr_SetString(PyExc_ValueError,
332 "length should not be negative");
333 goto error;
311 } 334 }
312 335
313 if (PySlice_GetIndicesEx((PyObject*)self, ilen, &start, &stop, 336 cmp = PyObject_RichCompareBool(step, zero, Py_EQ);
314 &step, &slicelength) < 0) { 337 if (cmp < 0) {
315 return NULL; 338 goto error;
339 }
340 if (cmp) {
341 PyErr_SetString(PyExc_ValueError,
342 "slice step cannot be zero");
343 goto error;
316 } 344 }
317 345
318 return Py_BuildValue("(nnn)", start, stop, step); 346 /* Find lower and upper bounds for start and stop. */
347 step_is_negative = PyObject_RichCompareBool(step, zero, Py_LT);
348 if (step_is_negative < 0) {
349 goto error;
350 }
351 if (step_is_negative) {
352 lower = PyLong_FromLong(-1L);
353 if (lower == NULL)
354 goto error;
355
356 upper = PyNumber_Add(length, lower);
357 if (upper == NULL)
358 goto error;
359 }
360 else {
361 lower = zero;
362 Py_INCREF(lower);
363 upper = length;
364 Py_INCREF(upper);
365 }
366
367 /* Compute start. */
368 if (self->start == Py_None) {
369 start = step_is_negative ? upper : lower;
370 Py_INCREF(start);
371 }
372 else {
373 start = PyNumber_Index(self->start);
374 if (start == NULL)
375 goto error;
376
377 cmp = PyObject_RichCompareBool(start, zero, Py_LT);
378 if (cmp < 0)
379 goto error;
380 if (cmp) {
381 /* start += length */
382 PyObject *tmp = PyNumber_Add(start, length);
383 Py_DECREF(start);
384 start = tmp;
385 if (start == NULL)
386 goto error;
387
388 cmp = PyObject_RichCompareBool(start, lower, Py_LE);
389 if (cmp < 0)
390 goto error;
391 if (cmp) {
392 Py_DECREF(start);
393 Py_INCREF(lower);
394 start = lower;
395 }
396 }
397 else {
398 cmp = PyObject_RichCompareBool(start, upper, Py_GE);
storchaka 2012/11/04 10:55:06 This is only bikeshedding, but I prefer Py_GT here
399 if (cmp < 0)
400 goto error;
401 if (cmp) {
402 Py_DECREF(start);
403 Py_INCREF(upper);
404 start = upper;
405 }
406 }
407 }
408
409 /* Compute stop. */
410 if (self->stop == Py_None) {
411 stop = step_is_negative ? lower : upper;
412 Py_INCREF(stop);
413 }
414 else {
415 stop = PyNumber_Index(self->stop);
416 if (stop == NULL)
417 goto error;
418
419 cmp = PyObject_RichCompareBool(stop, zero, Py_LT);
420 if (cmp < 0)
421 goto error;
422 if (cmp) {
423 /* stop += length */
424 PyObject *tmp = PyNumber_Add(stop, length);
425 Py_DECREF(stop);
426 stop = tmp;
427 if (stop == NULL)
428 goto error;
429
430 cmp = PyObject_RichCompareBool(stop, lower, Py_LE);
431 if (cmp < 0)
432 goto error;
433 if (cmp) {
434 Py_DECREF(stop);
435 Py_INCREF(lower);
436 stop = lower;
437 }
438 }
439 else {
440 cmp = PyObject_RichCompareBool(stop, upper, Py_GE);
441 if (cmp < 0)
442 goto error;
443 if (cmp) {
444 Py_DECREF(stop);
445 Py_INCREF(upper);
446 stop = upper;
447 }
448 }
449 }
450
451 Py_DECREF(upper);
452 Py_DECREF(lower);
453 Py_DECREF(length);
454 Py_DECREF(zero);
455 return Py_BuildValue("(NNN)", start, stop, step);
456
457 error:
458 Py_XDECREF(start);
459 Py_XDECREF(stop);
460 Py_XDECREF(step);
461 Py_XDECREF(upper);
462 Py_XDECREF(lower);
463 Py_XDECREF(length);
464 Py_XDECREF(zero);
465 return NULL;
319 } 466 }
467
320 468
321 PyDoc_STRVAR(slice_indices_doc, 469 PyDoc_STRVAR(slice_indices_doc,
322 "S.indices(len) -> (start, stop, stride)\n\ 470 "S.indices(len) -> (start, stop, stride)\n\
323 \n\ 471 \n\
324 Assuming a sequence of length len, calculate the start and stop\n\ 472 Assuming a sequence of length len, calculate the start and stop\n\
325 indices, and the stride length of the extended slice described by\n\ 473 indices, and the stride length of the extended slice described by\n\
326 S. Out of bounds indices are clipped in a manner consistent with the\n\ 474 S. Out of bounds indices are clipped in a manner consistent with the\n\
327 handling of normal slices."); 475 handling of normal slices.");
328 476
329 static PyObject * 477 static PyObject *
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 0, /* tp_getset */ 581 0, /* tp_getset */
434 0, /* tp_base */ 582 0, /* tp_base */
435 0, /* tp_dict */ 583 0, /* tp_dict */
436 0, /* tp_descr_get */ 584 0, /* tp_descr_get */
437 0, /* tp_descr_set */ 585 0, /* tp_descr_set */
438 0, /* tp_dictoffset */ 586 0, /* tp_dictoffset */
439 0, /* tp_init */ 587 0, /* tp_init */
440 0, /* tp_alloc */ 588 0, /* tp_alloc */
441 slice_new, /* tp_new */ 589 slice_new, /* tp_new */
442 }; 590 };
OLDNEW
« no previous file with comments | « Lib/test/test_slice.py ('k') | no next file » | no next file with comments »

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