mirror of
https://github.com/pellepl/spiffs.git
synced 2026-07-28 06:27:47 +00:00
fix range bug in ix memory mapping #98
This commit is contained in:
+14
-7
@@ -1127,6 +1127,7 @@ s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map,
|
||||
|
||||
map->map_buf = map_buf;
|
||||
map->offset = offset;
|
||||
// nb: spix range includes last
|
||||
map->start_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs);
|
||||
map->end_spix = (offset + len) / SPIFFS_DATA_PAGE_SIZE(fs);
|
||||
memset(map_buf, 0, sizeof(spiffs_page_ix) * (map->end_spix - map->start_spix + 1));
|
||||
@@ -1187,29 +1188,34 @@ s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) {
|
||||
if (spix_diff != 0) {
|
||||
// move vector
|
||||
int i;
|
||||
const s32_t vec_len = map->end_spix - map->start_spix + 1;
|
||||
const s32_t vec_len = map->end_spix - map->start_spix + 1; // spix range includes last
|
||||
map->start_spix += spix_diff;
|
||||
map->end_spix += spix_diff;
|
||||
if (spix_diff >= vec_len) {
|
||||
// moving beyond range
|
||||
memset(&map->map_buf, 0, vec_len * sizeof(spiffs_page_ix));
|
||||
res = spiffs_populate_ix_map(fs, fd, 0, vec_len);
|
||||
// populate_ix_map is inclusive
|
||||
res = spiffs_populate_ix_map(fs, fd, 0, vec_len-1);
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
} else if (spix_diff > 0) {
|
||||
// diff positive
|
||||
for (i = 0; i < vec_len - spix_diff - 1; i++) {
|
||||
for (i = 0; i < vec_len - spix_diff; i++) {
|
||||
map->map_buf[i] = map->map_buf[i + spix_diff];
|
||||
}
|
||||
memset(&map->map_buf[vec_len - spix_diff - 1], 0, spix_diff * sizeof(spiffs_page_ix));
|
||||
res = spiffs_populate_ix_map(fs, fd, vec_len - spix_diff, vec_len);
|
||||
// memset is non-inclusive
|
||||
memset(&map->map_buf[vec_len - spix_diff], 0, spix_diff * sizeof(spiffs_page_ix));
|
||||
// populate_ix_map is inclusive
|
||||
res = spiffs_populate_ix_map(fs, fd, vec_len - spix_diff, vec_len-1);
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
} else {
|
||||
// diff negative
|
||||
for (i = vec_len - 1; i >= -spix_diff; i--) {
|
||||
map->map_buf[i] = map->map_buf[i + spix_diff];
|
||||
}
|
||||
// memset is non-inclusive
|
||||
memset(&map->map_buf[0], 0, -spix_diff * sizeof(spiffs_page_ix));
|
||||
res = spiffs_populate_ix_map(fs, fd, 0, spix_diff);
|
||||
// populate_ix_map is inclusive
|
||||
res = spiffs_populate_ix_map(fs, fd, 0, -spix_diff - 1);
|
||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||
}
|
||||
|
||||
@@ -1221,7 +1227,8 @@ s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) {
|
||||
|
||||
s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes) {
|
||||
SPIFFS_API_CHECK_CFG(fs);
|
||||
return (bytes + (SPIFFS_DATA_PAGE_SIZE(fs) -1) ) / SPIFFS_DATA_PAGE_SIZE(fs);
|
||||
// always add one extra page, the offset might change to the middle of a page
|
||||
return (bytes + SPIFFS_DATA_PAGE_SIZE(fs) ) / SPIFFS_DATA_PAGE_SIZE(fs);
|
||||
}
|
||||
|
||||
s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries) {
|
||||
|
||||
@@ -708,6 +708,7 @@ static s32_t spiffs_populate_ix_map_v(
|
||||
return res;
|
||||
}
|
||||
|
||||
// populates index map, from vector entry start to vector entry end, inclusive
|
||||
s32_t spiffs_populate_ix_map(spiffs *fs, spiffs_fd *fd, u32_t vec_entry_start, u32_t vec_entry_end) {
|
||||
s32_t res;
|
||||
spiffs_ix_map *map = fd->ix_map;
|
||||
|
||||
+69
-15
@@ -2047,37 +2047,78 @@ TEST(ix_map_remap)
|
||||
|
||||
fd1 = SPIFFS_open(FS, "1", SPIFFS_O_RDONLY, 0);
|
||||
TEST_CHECK_GT(fd1, 0);
|
||||
printf(".. corresponding pix entries: %i\n", SPIFFS_bytes_to_ix_map_entries(FS, size));
|
||||
TEST_CHECK_EQ(SPIFFS_bytes_to_ix_map_entries(FS, size), size_pages);
|
||||
printf(".. corresponding pix entries: %i\n", SPIFFS_bytes_to_ix_map_entries(FS, size) + 1);
|
||||
TEST_CHECK_EQ(SPIFFS_bytes_to_ix_map_entries(FS, size), size_pages + 1);
|
||||
|
||||
// map index to memory
|
||||
// move around, check validity
|
||||
const int entries = SPIFFS_bytes_to_ix_map_entries(FS, size/2);
|
||||
spiffs_ix_map map;
|
||||
spiffs_page_ix ixbuf[entries];
|
||||
spiffs_page_ix ixbuf_ref[entries];
|
||||
// add one extra for stack safeguarding
|
||||
spiffs_page_ix ixbuf[entries+1];
|
||||
spiffs_page_ix ixbuf_ref[entries+1];
|
||||
const spiffs_page_ix canary = (spiffs_page_ix)0x87654321;
|
||||
memset(ixbuf, 0xee, sizeof(ixbuf));
|
||||
ixbuf[entries] = canary;
|
||||
|
||||
res = SPIFFS_ix_map(FS, fd1, &map, 0, size/2, ixbuf);
|
||||
TEST_CHECK_GE(res, SPIFFS_OK);
|
||||
|
||||
memcpy(ixbuf_ref, ixbuf, sizeof(ixbuf));
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
memcpy(ixbuf_ref, ixbuf, sizeof(spiffs_page_ix) * entries);
|
||||
|
||||
TEST_CHECK_EQ(SPIFFS_ix_remap(FS, fd1, 0), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(0, memcmp(ixbuf_ref, ixbuf, sizeof(ixbuf)));
|
||||
TEST_CHECK_EQ(canary, ixbuf[entries]);
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_EQ(0, memcmp(ixbuf_ref, ixbuf, sizeof(spiffs_page_ix) * entries));
|
||||
|
||||
TEST_CHECK_EQ(SPIFFS_ix_remap(FS, fd1, SPIFFS_DATA_PAGE_SIZE(FS)), SPIFFS_OK);
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_EQ(canary, ixbuf[entries]);
|
||||
TEST_CHECK_EQ(0, memcmp(&ixbuf_ref[1], ixbuf, sizeof(spiffs_page_ix) * (entries-1)));
|
||||
|
||||
|
||||
TEST_CHECK_EQ(SPIFFS_ix_remap(FS, fd1, 0), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(0, memcmp(ixbuf_ref, ixbuf, sizeof(ixbuf)));
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_EQ(canary, ixbuf[entries]);
|
||||
TEST_CHECK_EQ(0, memcmp(ixbuf_ref, ixbuf, sizeof(spiffs_page_ix) * entries));
|
||||
|
||||
TEST_CHECK_EQ(SPIFFS_ix_remap(FS, fd1, size/2), SPIFFS_OK);
|
||||
TEST_CHECK_EQ(canary, ixbuf[entries]);
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf_ref[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
int matches = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
int j;
|
||||
for (j = 0; j < entries; j++) {
|
||||
TEST_CHECK_NEQ(ixbuf_ref[i], ixbuf[j]);
|
||||
if (ixbuf_ref[i] == ixbuf[i]) {
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_CHECK_LE(matches, 1);
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
@@ -2180,15 +2221,18 @@ TEST(ix_map_beyond)
|
||||
const int entries = SPIFFS_bytes_to_ix_map_entries(FS, size);
|
||||
spiffs_ix_map map;
|
||||
spiffs_page_ix ixbuf[entries];
|
||||
printf("map has %i entries\n", entries);
|
||||
|
||||
printf("map 100-200%%\n");
|
||||
res = SPIFFS_ix_map(FS, fd, &map, size, size*2, ixbuf);
|
||||
res = SPIFFS_ix_map(FS, fd, &map, size, size, ixbuf);
|
||||
TEST_CHECK_GE(res, SPIFFS_OK);
|
||||
|
||||
// make sure map is empty
|
||||
printf("make sure map is empty\n");
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
TEST_CHECK_EQ(ixbuf[i], 0);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("elongate by 100%%\n");
|
||||
for (i = 0; i < size_pages; i++) {
|
||||
@@ -2203,19 +2247,25 @@ TEST(ix_map_beyond)
|
||||
size = s.size;
|
||||
printf("file elongated, size: %i..\n", size);
|
||||
|
||||
// make sure map is non-empty
|
||||
printf("make sure map is full but for one element\n");
|
||||
int zeroed = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
TEST_CHECK_NEQ(ixbuf[i], 0);
|
||||
printf("%04x ", ixbuf[i]);
|
||||
if (ixbuf[i] == 0) zeroed++;
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_LE(zeroed, 1);
|
||||
|
||||
printf("remap till end\n");
|
||||
TEST_CHECK_EQ(SPIFFS_ix_remap(FS, fd, size), SPIFFS_OK);
|
||||
|
||||
// make sure map is empty but for one element
|
||||
printf("make sure map is empty but for one element\n");
|
||||
int nonzero = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
printf("%04x ", ixbuf[i]);
|
||||
if (ixbuf[i]) nonzero++;
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_LE(nonzero, 1);
|
||||
|
||||
printf("elongate again, by other fd\n");
|
||||
@@ -2230,10 +2280,14 @@ TEST(ix_map_beyond)
|
||||
}
|
||||
TEST_CHECK_GE(SPIFFS_close(FS, fd2), SPIFFS_OK);
|
||||
|
||||
// make sure map is non-empty
|
||||
printf("make sure map is full but for one element\n");
|
||||
zeroed = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
TEST_CHECK_NEQ(ixbuf[i], 0);
|
||||
printf("%04x ", ixbuf[i]);
|
||||
if (ixbuf[i] == 0) zeroed++;
|
||||
}
|
||||
printf("\n");
|
||||
TEST_CHECK_LE(zeroed, 1);
|
||||
|
||||
return TEST_RES_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user