Archived
1
0
Fork 0

Enhanced reading and skipping methods

This commit is contained in:
Thomas Touhey 2016-11-02 13:32:33 +01:00
parent 203083a1e9
commit 56c9c0dc82
2 changed files with 50 additions and 14 deletions

View file

@ -186,7 +186,7 @@ struct g3a_subheader {
uint8_t icon[0x300];
/* unused */
uint8_t unused[0x92C];
uint8_t unused[0x92c];
/* G3A filename (seriously?!) */
uint8_t g3a_filename[0x144];

View file

@ -16,8 +16,13 @@
/* ************************************************************************** */
#define min(A, B) ((A) < (B) ? (A) : (B))
/* read with EOF check */
#define READ(TO, SZ) \
if (!fread(TO, SZ, 1, stream)) return (g1m_error_eof);
#define READ(TO, SZ) { \
size_t READ_size = fread(TO, 1, SZ, stream); \
if (READ_size < (SZ)) { \
log_info("READING failed: read %zu/%zu bytes, %zu missing.", \
READ_size, SZ, (SZ) - READ_size); \
return (g1m_error_eof); \
}}
/* read with EOF check, declare var before */
#define DREAD(NAM, STRUCT) \
struct STRUCT NAM; \
@ -33,6 +38,9 @@
* skip:
* Skip some bytes.
*
* I've made two loops to avoid conditions in each loop iteration
* when checksum is not calculated.
*
* @arg stream the stream where to skip bytes.
* @arg size the size to skip.
* @arg checksum pointer to the checksum variable if there is one.
@ -41,6 +49,7 @@
static int skip(FILE *stream, size_t size, uint_fast32_t *checksum)
{
uint8_t buf[1024];
size_t size_ini = size;
if (checksum) {
uint_fast32_t add = 0;
@ -49,13 +58,20 @@ static int skip(FILE *stream, size_t size, uint_fast32_t *checksum)
if (!size) break;
/* read that much */
size_t curlen = min(size, 1024);
READ(buf, curlen)
size -= curlen;
{
size_t curlen = min(size, 1024);
size_t read_len = fread(buf, 1, curlen, stream);
size -= read_len;
if (read_len < curlen) {
log_info("SKIPPING failed, skipped %zu/%zu bytes, "
"%zu missing", size_ini - size, size_ini, size);
return (g1m_error_eof);
}
/* feed the checksum */
for (size_t i = 0; i < curlen; i++)
add += buf[i];
/* feed the checksum */
for (size_t i = 0; i < curlen; i++)
add += buf[i];
}
}
*checksum += add;
} else {
@ -63,9 +79,17 @@ static int skip(FILE *stream, size_t size, uint_fast32_t *checksum)
/* if no size left, exit */
if (!size) break;
size_t curlen = min(size, 1024);
READ(buf, curlen);
size -= curlen;
/* read that much */
{
size_t curlen = min(size, 1024);
size_t read_len = fread(buf, 1, curlen, stream);
size -= read_len;
if (read_len < curlen) {
log_info("SKIPPING failed, skipped %zu/%zu bytes, "
"%zu missing", size_ini - size, size_ini, size);
return (g1m_error_eof);
}
}
}
}
@ -156,6 +180,10 @@ static int g1m_parse_addin(g1m_t *handle, FILE *stream)
log_info("version is %.10s", hd.version);
log_info("creation date is %.14s", hd.creation_date);
/* skip size */
SKIP(hd.filesize - sizeof(struct standard_header)
- sizeof(struct g1a_subheader))
/* no errors */
return (0);
}
@ -223,7 +251,7 @@ static int g1m_parse_mcs_spreadsheet(g1m_t *handle, FILE *stream)
/* get the row directory */
uint8_t row_directory[0x80];
READ(&row_directory, 0x80)
READ(&row_directory, (size_t)0x80)
/* initialize loop values */
uint8_t *rd = row_directory;
@ -501,6 +529,7 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
int err;
/* get e-act subheader */
if (bufsize < sizeof(struct eact_eactheader)) return (g1m_error_eof);
struct eact_eactheader ehd;
memcpy(&ehd, buf, sizeof(struct eact_eactheader));
@ -510,6 +539,9 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
/* get the line descriptors
* there is actually a "bonus" line descriptor at the end, but the
* fact that we're using offsets lets us unaware of it. */
if (bufsize < sizeof(struct eact_eactheader)
+ (ehd.line_count + 1) * sizeof(struct line_descriptor))
return (g1m_error_eof);
struct line_descriptor *lds = (void*)&buf[sizeof(struct eact_eactheader)];
/* browse the lines */
@ -535,6 +567,10 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
uint_fast8_t entry_type = lds[i].entry_type;
uint_fast32_t entry_offset = lds[i].entry_offset;
/* check if buffer is big enough */
if (entry_offset + linesize > bufsize)
return (g1m_error_eof);
/* log data */
log_info("[>%d][%ld] Is '%s' (0x%02x)", depth, i + 1,
g1m_get_eact_ltype_string(entry_type), entry_type);
@ -574,6 +610,7 @@ static int g1m_parse_eact_cont(g1m_t *handle, uint8_t *buf, size_t bufsize,
/* read content header */
size_t could_read = min(bufsize, sizeof(struct eact_contentheader));
if (could_read < 9) return (g1m_error_eof);
struct eact_contentheader hd = {};
memcpy(&hd, buf, could_read);
@ -630,7 +667,6 @@ static int g1m_parse_eact(g1m_t * handle, FILE *stream)
/* get content buffer */
size_t bufsize = hd.filesize - sizeof(struct standard_header)
- sizeof(struct eact_header) - hd.setup_area_size;
log_info("bufsize is %zuo", bufsize);
uint8_t buf[bufsize];
READ(&buf, bufsize)