Skip to content

Commit

Permalink
rsdos: initial_packet field is now returned correctly
Browse files Browse the repository at this point in the history
 * avoid passing parsedString struct into functions, as the
   scope change can completely break the contents if intentional
   null bytes are present
 * change parseString to allocate memory for string contents
   directly and copy the string into it
 * null characters are appending to the end of the string in
   read_string() itself
 * added parameter to read_string() to force null termination to
   NOT be added to the read string
 * ensure entire initial packet contents are returned by
   getRsdosPacketString(), not just up to the first null byte
  • Loading branch information
salcock committed Apr 21, 2021
1 parent 9649311 commit fb53434
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 32 deletions.
5 changes: 4 additions & 1 deletion src/pyavro_stardust/baseavro.pxd
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from libcpp.vector cimport vector
from cpython cimport array
import array


cdef struct parsedString:
unsigned int toskip
Expand All @@ -14,7 +17,7 @@ cdef struct parsedNumericArrayBlock:
cdef (unsigned int, long) read_long(const unsigned char[:] buf,
const unsigned int maxlen)
cdef parsedString read_string(const unsigned char[:] buf,
const unsigned int maxlen)
const unsigned int maxlen, int addNullTerm=*)
cdef parsedNumericArrayBlock read_numeric_array(const unsigned char[:] buf,
const unsigned int maxlen)

Expand Down
21 changes: 13 additions & 8 deletions src/pyavro_stardust/baseavro.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ from cpython.mem cimport PyMem_Malloc, PyMem_Free, PyMem_Realloc
import zlib, wandio, sys
cimport cython


cdef (unsigned int, long) read_long(const unsigned char[:] buf,
const unsigned int maxlen):
cdef unsigned int longlen = 0
Expand All @@ -31,7 +32,7 @@ cdef (unsigned int, long) read_long(const unsigned char[:] buf,
return (longlen + 1, (n >> 1) ^ -(n & 1))

cdef parsedString read_string(const unsigned char[:] buf,
const unsigned int maxlen):
const unsigned int maxlen, int addNullTerm=True):
cdef unsigned int skip
cdef long strlen
cdef parsedString s
Expand All @@ -45,7 +46,15 @@ cdef parsedString read_string(const unsigned char[:] buf,

s.toskip = skip
s.strlen = strlen
s.start = <unsigned char *>&(buf[skip])

if addNullTerm:
s.start = <unsigned char *>PyMem_Malloc(strlen + 1)
memcpy(s.start, &(buf[skip]), strlen)
s.start[strlen] = b'\x00'
else:
s.start = <unsigned char *>PyMem_Malloc(strlen)
memcpy(s.start, &(buf[skip]), strlen)

return s

cdef parsedNumericArrayBlock read_numeric_array(const unsigned char[:] buf,
Expand Down Expand Up @@ -184,17 +193,13 @@ cdef class AvroRecord:
if attrind < 0 or <unsigned int>attrind >= self.stringcount:
return 0

astr = read_string(buf, maxlen)
astr = read_string(buf, maxlen, True)

if astr.toskip == 0:
return 0

self.sizeinbuf += astr.toskip + astr.strlen
self.attributes_s[attrind] = <char *>PyMem_Malloc(sizeof(char) * astr.strlen + 1)

memcpy(self.attributes_s[attrind], astr.start, astr.strlen)
self.attributes_s[attrind][astr.strlen] = b'\x00'

self.attributes_s[attrind] = <char *>astr.start
return astr.toskip + astr.strlen

@cython.wraparound(False)
Expand Down
11 changes: 5 additions & 6 deletions src/pyavro_stardust/rsdos.pxd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import cython
cimport cython
from pyavro_stardust.baseavro cimport AvroRecord, AvroReader, parsedString

cpdef enum RsdosAttribute:
Expand All @@ -19,21 +19,20 @@ cpdef enum RsdosAttribute:
ATTR_RSDOS_LATEST_TIME_USEC = 14
ATTR_RSDOS_LAST_ATTRIBUTE = 15

@cython.final
cdef class AvroRsdos(AvroRecord):

cdef unsigned char *packetcontent
cdef public int pktcontentlen
cdef public unsigned int pktcontentlen

cpdef dict asDict(self)
cpdef void resetRecord(self)
cdef void setRsdosPacketString(self, parsedString astr)
cpdef bytes getRsdosPacketString(self)
cpdef int setRsdosPacketString(self, const unsigned char[:] buf,
const unsigned int maxlen)

@cython.final
cdef class AvroRsdosReader(AvroReader):
cdef int _parseNextRecord(self, const unsigned char[:] buf,
const int maxlen)
const unsigned int maxlen)


# vim: set sw=4 tabstop=4 softtabstop=4 expandtab :
40 changes: 23 additions & 17 deletions src/pyavro_stardust/rsdos.pyx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

# cython: language_level=3
cimport cython
from cpython.mem cimport PyMem_Free
from pyavro_stardust.baseavro cimport AvroRecord, read_long, read_string, \
AvroReader, parsedString

Expand Down Expand Up @@ -33,7 +34,7 @@ cdef class AvroRsdos(AvroRecord):
if self.pktcontentlen == 0:
initpkt = None
else:
initpkt = <bytes>self.packetcontent
initpkt = self.getRsdosPacketString()

return {
"timestamp": self.attributes_l[<int>ATTR_RSDOS_TIMESTAMP],
Expand All @@ -57,14 +58,25 @@ cdef class AvroRsdos(AvroRecord):

cpdef void resetRecord(self):
self.pktcontentlen = 0
if self.packetcontent != NULL:
PyMem_Free(self.packetcontent)
super(AvroRsdos, self).resetRecord()

cdef void setRsdosPacketString(self, parsedString astr):
cpdef bytes getRsdosPacketString(self):
return <bytes>self.packetcontent[:self.pktcontentlen]

cpdef int setRsdosPacketString(self, const unsigned char[:] buf,
const unsigned int maxlen):

cdef parsedString astr

astr = read_string(buf, maxlen, addNullTerm=False)
if astr.toskip == 0:
return 0
self.packetcontent = astr.start
self.pktcontentlen = astr.strlen

cpdef bytes getRsdosPacketString(self):
return <bytes>self.packetcontent
self.sizeinbuf += astr.toskip + astr.strlen
return 1

@cython.final
cdef class AvroRsdosReader(AvroReader):
Expand All @@ -73,12 +85,11 @@ cdef class AvroRsdosReader(AvroReader):
super().__init__(filepath)
self.currentrec = AvroRsdos()

cdef int _parseNextRecord(self, const unsigned char[:] buf,
const int maxlen):
cdef int _parseNextRecord(self, const unsigned char[:] buf,
const unsigned int maxlen):

cdef int offset, offinc
cdef unsigned int offset, offinc
cdef RsdosAttribute i
cdef parsedString astr

if maxlen == 0:
return 0
Expand All @@ -89,17 +100,12 @@ cdef class AvroRsdosReader(AvroReader):
for i in range(0, ATTR_RSDOS_LATEST_TIME_USEC + 1):
offinc = self.currentrec.parseNumeric(buf[offset:],
maxlen - offset, i)
if offinc <= 0:
if offinc == 0:
return 0
offset += offinc

astr = read_string(buf[offset:], maxlen - offset)
if astr.toskip == 0:
return 0

self.currentrec.setRsdosPacketString(astr)
self.currentrec.sizeinbuf += astr.toskip + astr.strlen
return 1
return self.currentrec.setRsdosPacketString(buf[offset:],
maxlen - offset);


# vim: set sw=4 tabstop=4 softtabstop=4 expandtab :

0 comments on commit fb53434

Please sign in to comment.