Skip to content

Commit 3adaee4

Browse files
authored
Merge pull request #30 from nattgris/od_load
Fix multiple data corruption in OD load
2 parents 845798b + e9627cf commit 3adaee4

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

src/co_od.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ uint32_t co_od_load (co_net_t * net, co_store_t store)
374374
uint16_t index;
375375
uint8_t subindex;
376376
size_t size;
377-
uint64_t value;
377+
uint64_t value = 0;
378378
uint8_t * ptr;
379379
uint32_t abort;
380380

@@ -398,7 +398,14 @@ uint32_t co_od_load (co_net_t * net, co_store_t store)
398398
if (entry == NULL || !(entry->flags & OD_WRITE))
399399
continue;
400400

401-
if (size > sizeof (value))
401+
if (size <= sizeof (value))
402+
{
403+
if (net->read (arg, &value, size) < 0)
404+
goto error;
405+
406+
co_od_set_value (net, obj, entry, subindex, value);
407+
}
408+
else if (size == CO_BYTELENGTH (entry->bitlength))
402409
{
403410
/* Get pointer to storage */
404411
abort = co_od_get_ptr (net, obj, entry, subindex, &ptr);
@@ -410,10 +417,16 @@ uint32_t co_od_load (co_net_t * net, co_store_t store)
410417
}
411418
else
412419
{
420+
/* Stored size does not match object size. Discard data. */
421+
while (size > sizeof(value))
422+
{
423+
if (net->read (arg, &value, sizeof (value)) < 0)
424+
goto error;
425+
size -= sizeof(value);
426+
}
427+
413428
if (net->read (arg, &value, size) < 0)
414429
goto error;
415-
416-
co_od_set_value (net, obj, entry, subindex, value);
417430
}
418431
}
419432

test/test_od.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,57 @@ TEST_F (OdTest, StoreThenLoadOD)
239239
EXPECT_EQ (0x12345678u, value);
240240
}
241241

242+
TEST_F (OdTest, StoreThenLoadNewOD)
243+
{
244+
uint32_t value2000_01;
245+
uint32_t value2000_02;
246+
char str2001[16];
247+
char expect_str2001[sizeof(str2001)] = {0};
248+
const co_entry_t OD2000_1[] = {
249+
{0x00, OD_RO, DTYPE_UNSIGNED8, 8, 0x02, NULL},
250+
{0x01, OD_RW, DTYPE_UNSIGNED32, 32, 0, &value2000_01},
251+
{0x02, OD_RW, DTYPE_UNSIGNED16, 16, 0, &value2000_02},
252+
};
253+
co_entry_t OD2001_1[] = {
254+
{0, OD_RW, DTYPE_VISIBLE_STRING, 8 * sizeof (str2001), 0, str2001},
255+
};
256+
const co_obj_t OD1[] = {
257+
{0x2000, OTYPE_RECORD, 2, OD2000_1, NULL},
258+
{0x2001, OTYPE_VAR, 0, OD2001_1, NULL},
259+
{0, OTYPE_NULL, 0, NULL, NULL},
260+
};
261+
const co_entry_t OD2000_2[12] = {
262+
{0x00, OD_RO, DTYPE_UNSIGNED8, 8, 0x02, NULL},
263+
{0x01, OD_RW, DTYPE_UNSIGNED16, 16, 0, &value2000_01}, // Grows
264+
{0x02, OD_RW, DTYPE_UNSIGNED32, 32, 0, &value2000_02}, // Shrinks
265+
};
266+
co_entry_t OD2001_2[] = {
267+
// Shrinks, should discard data
268+
{0, OD_RW, DTYPE_VISIBLE_STRING, 8 * (sizeof (str2001) - 1), 0, str2001},
269+
};
270+
const co_obj_t OD2[] = {
271+
{0x2000, OTYPE_RECORD, 2, OD2000_2, NULL},
272+
{0x2001, OTYPE_VAR, 0, OD2001_2, NULL},
273+
{0, OTYPE_NULL, 0, NULL, NULL},
274+
};
275+
276+
net.od = OD1;
277+
value2000_01 = 0xFFFFFFFF;
278+
value2000_02 = 0xFFFF;
279+
memset (str2001, 0xFF, sizeof(str2001));
280+
co_od_store (&net, CO_STORE_APP, 0x2000, 0x2FFF);
281+
282+
value2000_01 = 0xAAAAAAAA;
283+
value2000_02 = 0x55555555;
284+
memset (str2001, 0xAA, sizeof(str2001));
285+
286+
net.od = OD2;
287+
co_od_reset (&net, CO_STORE_APP, 0x2000, 0x2FFF);
288+
EXPECT_EQ (0xAAAAFFFFu, value2000_01);
289+
EXPECT_EQ (0x0000FFFFu, value2000_02);
290+
EXPECT_EQ (0, memcmp (expect_str2001, str2001, sizeof(str2001) - 1));
291+
}
292+
242293
TEST_F (OdTest, OD1010)
243294
{
244295
const co_obj_t * obj1010 = find_obj (0x1010);

0 commit comments

Comments
 (0)