Skip to content

Commit 2c55dcd

Browse files
committed
proper null termination of remark string
this might cause issues in other c libraries otherwise. document and fix null termination
1 parent 75b69bc commit 2c55dcd

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

package/MDAnalysis/lib/formats/include/readdcd.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ int write_dcdheader(fio_fd fd, const char *remarks, int N,
739739
fio_write_int32(fd, 3); /* the number of 80 character title strings */
740740

741741
strncpy(title_string, remarks, 240);
742+
// Enforce null-termination for long remark strings.
743+
// Not a problem for MDAnalysis but maybe for other readers.
744+
title_string[239] = '\0';
742745
WRITE(fd, title_string, 240);
743746

744747
fio_write_int32(fd, 244);

package/MDAnalysis/lib/formats/libdcd.pyx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,8 @@ cdef class DCDFile:
468468
Parameters
469469
----------
470470
remarks : str
471-
remarks of DCD file. Shouldn't be more then 240 characters (ASCII)
471+
remarks of DCD file. Writes up to 239 characters (ASCII). The
472+
character 240 will be the null terminator
472473
natoms : int
473474
number of atoms to write
474475
istart : int
@@ -479,6 +480,7 @@ cdef class DCDFile:
479480
integrator time step. The time for 1 frame is nsavc * delta
480481
is_periodic : bool
481482
write unitcell information. Also pretends that file was written by CHARMM 24
483+
482484
"""
483485
if not self.is_open:
484486
raise IOError("No file open")

testsuite/MDAnalysisTests/formats/test_libdcd.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ def write_dcd(in_name, out_name, remarks='testing', header=None):
318318

319319
@given(remarks=strategies.text(
320320
alphabet=string.printable, min_size=0,
321-
max_size=240)) # handle the printable ASCII strings
321+
max_size=239)) # handle the printable ASCII strings
322322
@example(remarks='')
323323
def test_written_remarks_property(remarks, tmpdir, dcd):
324324
# property based testing for writing of a wide range of string
@@ -327,7 +327,7 @@ def test_written_remarks_property(remarks, tmpdir, dcd):
327327
header = dcd.header
328328
header['remarks'] = remarks
329329
write_dcd(DCD, testfile, header=header)
330-
expected_remarks = remarks[:240]
330+
expected_remarks = remarks
331331
with DCDFile(testfile) as f:
332332
assert f.header['remarks'] == expected_remarks
333333

@@ -340,6 +340,8 @@ def written_dcd(tmpdir_factory):
340340
testfile = str(testfile)
341341
write_dcd(DCD, testfile)
342342
Result = namedtuple("Result", "testfile, header, orgfile")
343+
# throw away last char we didn't save due to null termination
344+
header['remarks'] = header['remarks'][:-1]
343345
return Result(testfile, header, DCD)
344346

345347

0 commit comments

Comments
 (0)