Skip to content

Commit 02eec3b

Browse files
committed
TST: Restrict accepted shapes to plausible vectors
Coercing vector to float before checking size could cause memory blow-up
1 parent 1566d9b commit 02eec3b

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

nibabel/freesurfer/io.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,20 @@ def write_morph_data(file_like, values, fnum=0):
179179
in binary write (`'wb'` mode, implementing the `write` method)
180180
values : array-like
181181
Surface morphometry values
182+
183+
Shape must be (N,), (N, 1), (1, N) or (N, 1, 1)
182184
fnum : int, optional
183185
Number of faces in the associated surface
184186
"""
185187
magic_bytes = np.array([255, 255, 255], dtype=np.uint8)
186188

187-
array = np.asarray(values).astype('>f4').squeeze()
188-
if len(array.shape) > 1:
189-
raise ValueError("Multi-dimensional values not supported")
189+
vector = np.asarray(values)
190+
vnum = np.prod(vector.shape)
191+
if vector.shape not in ((vnum,), (vnum, 1), (1, vnum), (vnum, 1, 1)):
192+
raise ValueError("Invalid shape: argument values must be a vector")
190193

191194
i4info = np.iinfo('i4')
192-
if len(array) > i4info.max:
195+
if vnum > i4info.max:
193196
raise ValueError("Too many values for morphometry file")
194197
if not i4info.min <= fnum <= i4info.max:
195198
raise ValueError("Argument fnum must be between {0} and {1}".format(
@@ -199,9 +202,9 @@ def write_morph_data(file_like, values, fnum=0):
199202
fobj.write(magic_bytes)
200203

201204
# vertex count, face count (unused), vals per vertex (only 1 supported)
202-
fobj.write(np.array([len(array), fnum, 1], dtype='>i4'))
205+
fobj.write(np.array([vnum, fnum, 1], dtype='>i4'))
203206

204-
fobj.write(array)
207+
fobj.write(vector.astype('>f4'))
205208

206209

207210
def read_annot(filepath, orig_ids=False):

nibabel/freesurfer/tests/test_io.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def test_write_morph_data():
104104
"""Test write_morph_data edge cases"""
105105
values = np.arange(20, dtype='>f4')
106106
okay_shapes = [(20,), (20, 1), (20, 1, 1), (1, 20)]
107-
bad_shape = (10, 2)
107+
bad_shapes = [(10, 2), (1, 1, 20, 1, 1)]
108108
big_num = np.iinfo('i4').max + 1
109109
with InTemporaryDirectory():
110110
for shape in okay_shapes:
@@ -113,10 +113,11 @@ def test_write_morph_data():
113113
assert_equal(values, read_morph_data('test.curv'))
114114
assert_raises(ValueError, write_morph_data, 'test.curv',
115115
np.zeros(shape), big_num)
116-
assert_raises(ValueError, write_morph_data, 'test.curv',
117-
values.reshape(bad_shape))
118116
assert_raises(ValueError, write_morph_data, 'test.curv',
119117
strided_scalar((big_num,)))
118+
for shape in bad_shapes:
119+
assert_raises(ValueError, write_morph_data, 'test.curv',
120+
values.reshape(shape))
120121

121122

122123
@freesurfer_test

0 commit comments

Comments
 (0)