Skip to content

Commit 91cfcb4

Browse files
committed
BUG: Fix out-of-bounds segfault in pad_object and backfill_object methods
1 parent d9b5df6 commit 91cfcb4

File tree

5 files changed

+66
-2
lines changed

5 files changed

+66
-2
lines changed

RELEASE.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,9 @@ pandas 0.7.0
217217
- Catch misreported console size when running IPython within Emacs
218218
- Fix minor bug in pivot table margins, loss of index names and length-1
219219
'All' tuple in row labels
220-
- Add support for legacy
220+
- Add support for legacy WidePanel objects to be read from HDFStore
221+
- Fix out-of-bounds segfault in pad_object and backfill_object methods when
222+
either source or target array are empty
221223

222224
Thanks
223225
------

pandas/src/generate_code.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ def backfill_%(name)s(ndarray[%(c_type)s] oldIndex,
147147
fill_vec = np.empty(len(newIndex), dtype = np.int32)
148148
fill_vec.fill(-1)
149149
150+
if oldLength == 0 or newLength == 0:
151+
return fill_vec
152+
150153
oldPos = oldLength - 1
151154
newPos = newLength - 1
152155
@@ -221,6 +224,9 @@ def pad_%(name)s(ndarray[%(c_type)s] oldIndex,
221224
fill_vec = np.empty(len(newIndex), dtype = np.int32)
222225
fill_vec.fill(-1)
223226
227+
if oldLength == 0 or newLength == 0:
228+
return fill_vec
229+
224230
oldPos = 0
225231
newPos = 0
226232

pandas/src/generated.pyx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ def pad_float64(ndarray[float64_t] oldIndex,
216216
fill_vec = np.empty(len(newIndex), dtype = np.int32)
217217
fill_vec.fill(-1)
218218

219+
if oldLength == 0 or newLength == 0:
220+
return fill_vec
221+
219222
oldPos = 0
220223
newPos = 0
221224

@@ -271,6 +274,9 @@ def pad_object(ndarray[object] oldIndex,
271274
fill_vec = np.empty(len(newIndex), dtype = np.int32)
272275
fill_vec.fill(-1)
273276

277+
if oldLength == 0 or newLength == 0:
278+
return fill_vec
279+
274280
oldPos = 0
275281
newPos = 0
276282

@@ -326,6 +332,9 @@ def pad_int32(ndarray[int32_t] oldIndex,
326332
fill_vec = np.empty(len(newIndex), dtype = np.int32)
327333
fill_vec.fill(-1)
328334

335+
if oldLength == 0 or newLength == 0:
336+
return fill_vec
337+
329338
oldPos = 0
330339
newPos = 0
331340

@@ -381,6 +390,9 @@ def pad_int64(ndarray[int64_t] oldIndex,
381390
fill_vec = np.empty(len(newIndex), dtype = np.int32)
382391
fill_vec.fill(-1)
383392

393+
if oldLength == 0 or newLength == 0:
394+
return fill_vec
395+
384396
oldPos = 0
385397
newPos = 0
386398

@@ -436,6 +448,9 @@ def pad_bool(ndarray[uint8_t] oldIndex,
436448
fill_vec = np.empty(len(newIndex), dtype = np.int32)
437449
fill_vec.fill(-1)
438450

451+
if oldLength == 0 or newLength == 0:
452+
return fill_vec
453+
439454
oldPos = 0
440455
newPos = 0
441456

@@ -492,6 +507,9 @@ def backfill_float64(ndarray[float64_t] oldIndex,
492507
fill_vec = np.empty(len(newIndex), dtype = np.int32)
493508
fill_vec.fill(-1)
494509

510+
if oldLength == 0 or newLength == 0:
511+
return fill_vec
512+
495513
oldPos = oldLength - 1
496514
newPos = newLength - 1
497515

@@ -541,6 +559,9 @@ def backfill_object(ndarray[object] oldIndex,
541559
fill_vec = np.empty(len(newIndex), dtype = np.int32)
542560
fill_vec.fill(-1)
543561

562+
if oldLength == 0 or newLength == 0:
563+
return fill_vec
564+
544565
oldPos = oldLength - 1
545566
newPos = newLength - 1
546567

@@ -590,6 +611,9 @@ def backfill_int32(ndarray[int32_t] oldIndex,
590611
fill_vec = np.empty(len(newIndex), dtype = np.int32)
591612
fill_vec.fill(-1)
592613

614+
if oldLength == 0 or newLength == 0:
615+
return fill_vec
616+
593617
oldPos = oldLength - 1
594618
newPos = newLength - 1
595619

@@ -639,6 +663,9 @@ def backfill_int64(ndarray[int64_t] oldIndex,
639663
fill_vec = np.empty(len(newIndex), dtype = np.int32)
640664
fill_vec.fill(-1)
641665

666+
if oldLength == 0 or newLength == 0:
667+
return fill_vec
668+
642669
oldPos = oldLength - 1
643670
newPos = newLength - 1
644671

@@ -688,6 +715,9 @@ def backfill_bool(ndarray[uint8_t] oldIndex,
688715
fill_vec = np.empty(len(newIndex), dtype = np.int32)
689716
fill_vec.fill(-1)
690717

718+
if oldLength == 0 or newLength == 0:
719+
return fill_vec
720+
691721
oldPos = oldLength - 1
692722
newPos = newLength - 1
693723

pandas/tests/test_tseries.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,32 @@ def test_get_reverse_indexer():
236236
expected = np.array([4, 2, 3, 6, 7], dtype='i4')
237237
assert(np.array_equal(result, expected))
238238

239+
def test_pad_backfill_object_segfault():
240+
from datetime import datetime
241+
old = np.array([], dtype='O')
242+
new = np.array([datetime(2010, 12, 31)], dtype='O')
243+
244+
result = lib.pad_object(old, new, lib.map_indices_object(old),
245+
lib.map_indices_object(new))
246+
expected = np.array([-1], dtype='i4')
247+
assert(np.array_equal(result, expected))
248+
249+
result = lib.pad_object(new, old, lib.map_indices_object(new),
250+
lib.map_indices_object(old))
251+
expected = np.array([], dtype='i4')
252+
assert(np.array_equal(result, expected))
253+
254+
result = lib.backfill_object(old, new, lib.map_indices_object(old),
255+
lib.map_indices_object(new))
256+
expected = np.array([-1], dtype='i4')
257+
assert(np.array_equal(result, expected))
258+
259+
result = lib.backfill_object(new, old, lib.map_indices_object(new),
260+
lib.map_indices_object(old))
261+
expected = np.array([], dtype='i4')
262+
assert(np.array_equal(result, expected))
263+
264+
239265
class TestTypeInference(unittest.TestCase):
240266

241267
def test_integers(self):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@
167167
MAJOR = 0
168168
MINOR = 7
169169
MICRO = 0
170-
ISRELEASED = True
170+
ISRELEASED = False
171171
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
172172
QUALIFIER = 'rc1'
173173

0 commit comments

Comments
 (0)