Skip to content

Commit b3242e8

Browse files
spreekergijzelaerr
authored andcommitted
improvements to s7util
prevent writing data to read only part of spec add row_offset, to add more write protection add key checking, ignoring empty rows prevent writing data to read only part of spec better check parameters when setting data
1 parent bd99216 commit b3242e8

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

snap7/util.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from collections import OrderedDict
1111
import struct
12+
import logging
1213

1314

1415
def parse_specification(db_specification):
@@ -61,6 +62,8 @@ def set_int(_bytearray, byte_index, _int):
6162
"""
6263
Set value in bytearray to int
6364
"""
65+
# make sure were dealing with an int
66+
_int = int(_int)
6467
# int needs two be two bytes.
6568
byte0 = _int >> 8
6669
byte1 = _int - (byte0 << 8)
@@ -109,6 +112,7 @@ def set_string(_bytearray, byte_index, value):
109112
:params value: string data
110113
:params size: total possible string size
111114
"""
115+
assert isinstance(value, (str, unicode))
112116
# set len count
113117
_bytearray[byte_index + 1] = len(value)
114118
i = 0
@@ -137,6 +141,7 @@ def get_dword(_bytearray, byte_index):
137141

138142

139143
def set_dword(_bytearray, byte_index, dword):
144+
dword = int(dword)
140145
_bytes = struct.unpack('4B', struct.pack('I', dword))
141146
for i, b in enumerate(_bytes):
142147
_bytearray[byte_index + i] = b
@@ -153,11 +158,14 @@ class DB(object):
153158
layout_offset = None # at which byte in row specification should
154159
# we start reading the data
155160
db_offset = None # at which byte in db should we start reading?
156-
# first fields could be used for something else
161+
# first fields could be be status data.
162+
# and only the last part could be control data
163+
# now you can be sure you will never overwrite
164+
# critical parts of db
157165

158166
def __init__(self, db_number, _bytearray,
159167
specification, row_size, size, id_field=None,
160-
db_offset=0, layout_offset=0):
168+
db_offset=0, layout_offset=0, row_offset=0):
161169

162170
self.db_number = db_number
163171
self.size = size
@@ -166,6 +174,8 @@ def __init__(self, db_number, _bytearray,
166174

167175
self.db_offset = db_offset
168176
self.layout_offset = layout_offset
177+
self.row_offset = row_offset
178+
169179
self._bytearray = _bytearray
170180
self.specification = specification
171181
# loop over bytearray. make rowObjects
@@ -187,10 +197,15 @@ def make_rows(self):
187197
specification,
188198
row_size=row_size,
189199
db_offset=db_offset,
190-
layout_offset=layout_offset)
200+
layout_offset=layout_offset,
201+
row_offset=self.row_offset)
191202

192203
# store row object
193204
key = row[id_field] if id_field else i
205+
if key and key in self.index:
206+
msg = '%s not unique!' % key
207+
logging.error(msg)
208+
print msg
194209
self.index[key] = row
195210

196211
def __getitem__(self, key, default=None):
@@ -216,11 +231,12 @@ class DB_Row(object):
216231
_specification = None # row specification
217232

218233
def __init__(self, _bytearray, _specification, row_size=0,
219-
db_offset=0, layout_offset=0):
234+
db_offset=0, layout_offset=0, row_offset=0):
220235

221236
self.db_offset = db_offset # start point of row data in db
222237
self.layout_offset = layout_offset # start point of row data in layout
223238
self.row_size = row_size
239+
self.row_offset = row_offset # start of writable part of row
224240

225241
assert(isinstance(_bytearray, (bytearray, DB)))
226242
self._bytearray = _bytearray
@@ -335,8 +351,15 @@ def write(self, client):
335351

336352
db_nr = self._bytearray.db_number
337353
offset = self.db_offset
338-
data = self.get_bytearray()[offset:offset+self.row_size]
339-
client.db_write(db_nr, self.db_offset, data)
354+
data = self.get_bytearray()[offset:offset+self.row_size]
355+
db_offset = self.db_offset
356+
357+
# indicate start of write only area of row!
358+
if self.row_offset:
359+
data = data[self.row_offset:]
360+
db_offset += self.row_offset
361+
362+
client.db_write(db_nr, db_offset, data)
340363

341364
def read(self, client):
342365
"""

0 commit comments

Comments
 (0)