diff --git a/include/libg1m.h b/include/libg1m.h index 97a42e6..d3c47d4 100644 --- a/include/libg1m.h +++ b/include/libg1m.h @@ -98,7 +98,7 @@ extern int g1m_make_fkey(g1m_t **handle, g1m_platform_t platform, int count); extern int g1m_make_lang(g1m_t **handle, g1m_platform_t platform, int count); extern int g1m_make_picture(g1m_t **handle, unsigned int width, unsigned int height); -extern int g1m_make_addin(g1m_t **h, g1m_platform_t platform, +extern int g1m_make_addin(g1m_t **h, g1m_platform_t platform, size_t size, const g1m_version_t *version, const time_t *created); /* encode a handle, get the extension */ diff --git a/include/libg1m/handle.h b/include/libg1m/handle.h index 5eb26e6..75336d5 100644 --- a/include/libg1m/handle.h +++ b/include/libg1m/handle.h @@ -68,21 +68,14 @@ typedef struct { char intname[12]; g1m_version_t version; time_t creation_date; + unsigned char *content; + size_t size; - /* Tab-related properties */ - int count; - int _size; - - /* MCS list */ + /* Lists for various purposes */ + int count, _size; g1m_mcsfile_t **files; - - /* Storage files list */ g1m_file_t **sfiles; - - /* Messages list */ char **messages; - - /* Function keys */ uint32_t ***fkeys; /* Picture-related data (also used for add-in icons */ diff --git a/include/libg1m/internals/log.h b/include/libg1m/internals/log.h index a9ec971..0bb0b82 100644 --- a/include/libg1m/internals/log.h +++ b/include/libg1m/internals/log.h @@ -28,10 +28,16 @@ /* Some printf types */ # ifdef _WIN64 # define PRIuSIZE "l64u" +# define PRIxSIZE "l64x" +# define PRIXSIZE "l64X" # elif _WIN32 # define PRIuSIZE "u" +# define PRIxSIZE "x" +# define PRIXSIZE "X" # else # define PRIuSIZE "zu" +# define PRIxSIZE "zx" +# define PRIXSIZE "zX" # endif /* ************************************************************************** */ diff --git a/src/decode/std/addin.c b/src/decode/std/addin.c index 5f67ffb..e37cea2 100644 --- a/src/decode/std/addin.c +++ b/src/decode/std/addin.c @@ -43,7 +43,10 @@ int g1m_decode_std_addin(g1m_t **h, g1m_buffer_t *buffer, /* make the handle */ g1m_version_t version; g1m_decode_version((char*)hd.version, &version); time_t created; g1m_decode_date((char*)hd.creation_date, &created); - err = g1m_make_addin(h, g1m_platform_fx, &version, &created); + size_t content_size = hd.filesize; /* already corrected */ + content_size -= sizeof(struct standard_header) + + sizeof(struct g1a_subheader); + err = g1m_make_addin(h, g1m_platform_fx, content_size, &version, &created); if (err) return (err); g1m_t *handle = *h; @@ -67,12 +70,14 @@ int g1m_decode_std_addin(g1m_t **h, g1m_buffer_t *buffer, g1m_decode_picture(handle->icon_sel, g1m_pictureformat_1bit_packed_r, hd.icon, handle->width, handle->height); - /* skip size */ - SKIP(hd.filesize - sizeof(struct standard_header) - - sizeof(struct g1a_subheader)) + /* read content */ + GREAD(handle->content, handle->size) /* no errors */ return (err); +fail: + g1m_free(*h); *h = NULL; + return (err); } /* ************************************************************************** */ @@ -104,7 +109,8 @@ int g1m_decode_std_cp_addin(g1m_t **h, g1m_buffer_t *buffer, /* make the handle */ g1m_version_t version; g1m_decode_version((char*)sub->version, &version); time_t created; g1m_decode_date((char*)sub->timestamp, &created); - err = g1m_make_addin(h, g1m_platform_cp, &version, &created); + size_t content_size = be32toh(sub->filesize) - 0x1000; + err = g1m_make_addin(h, g1m_platform_cp, content_size, &version, &created); if (err) return (err); g1m_t *handle = *h; @@ -127,10 +133,9 @@ int g1m_decode_std_cp_addin(g1m_t **h, g1m_buffer_t *buffer, handle->version.minor, handle->version.revision); log_info("timestamp is %.24s", ctime(&handle->creation_date)); - /* skip content for now */ - size_t content_size = be32toh(sub->filesize) - 0x1000; - if ((err = g1m_skip(buffer, content_size, check))) - goto fail; + /* get content */ + GREAD(handle->content, handle->size) + *check = g1m_checksum32(handle->content, handle->size, *check); /* no error */ return (0); @@ -168,7 +173,13 @@ int g1m_decode_std_cg_addin(g1m_t **h, g1m_buffer_t *buffer, /* make the handle */ g1m_version_t version; g1m_decode_version((char*)sub->version, &version); time_t created; g1m_decode_date((char*)sub->timestamp, &created); - err = g1m_make_addin(h, g1m_platform_cg, &version, &created); + size_t content_size = be32toh(sub->filesize); + content_size -= sizeof(struct standard_header) + + sizeof(struct standard_subheader) + + sizeof(struct _prizm_subheader) + sizeof(struct g3a_subheader) + + sizeof(uint32_t); + log_info("Content size is %" PRIuSIZE, content_size); + err = g1m_make_addin(h, g1m_platform_cg, content_size, &version, &created); if (err) return (err); g1m_t *handle = *h; @@ -191,10 +202,9 @@ int g1m_decode_std_cg_addin(g1m_t **h, g1m_buffer_t *buffer, handle->version.minor, handle->version.revision); log_info("timestamp is %.24s", ctime(&handle->creation_date)); - /* skip content for now */ - size_t content_size = be32toh(sub->filesize) - 4 - 0x7000; - if ((err = g1m_skip(buffer, content_size, check))) - goto fail; + /* read content */ + GREAD(handle->content, handle->size) + *check = g1m_checksum32(handle->content, handle->size, *check); /* no error */ return (0); diff --git a/src/manage/handle.c b/src/manage/handle.c index 04620f5..51ead67 100644 --- a/src/manage/handle.c +++ b/src/manage/handle.c @@ -173,20 +173,23 @@ fail: * * @arg h pointer to the handle to create. * @arg platform the platform for which to make the add-in. + * @arg size the code size. * @arg version the version of the add-in. * @arg created the creation date of the add-in. * @return the error code (0 if ok). */ -int g1m_make_addin(g1m_t **h, g1m_platform_t platform, +int g1m_make_addin(g1m_t **h, g1m_platform_t platform, size_t size, const g1m_version_t *version, const time_t *created) { *h = NULL; - /* check the platform */ + /* make checks */ if (platform != g1m_platform_fx && platform != g1m_platform_cg && platform != g1m_platform_cp) return (g1m_error_op); + if (platform == g1m_platform_fx && size > 512 * 1024) + return (g1m_error_op); /* allocate the handle */ *h = malloc(sizeof(g1m_t)); @@ -199,6 +202,11 @@ int g1m_make_addin(g1m_t **h, g1m_platform_t platform, handle->platform = platform; handle->version = *version; handle->creation_date = *created; + handle->size = size; + + /* allocate the content */ + handle->content = malloc(size); + if (!handle->content) goto fail; /* check the platform */ unsigned int width, height; @@ -250,6 +258,7 @@ void g1m_free(g1m_t *handle) /* addin time! */ if (handle->type & g1m_type_addin) { + free(handle->content); free(handle->icon_unsel); free(handle->icon_sel); } diff --git a/src/utils/buffer.c b/src/utils/buffer.c index 264cb06..fc92a40 100644 --- a/src/utils/buffer.c +++ b/src/utils/buffer.c @@ -45,12 +45,6 @@ int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size) if (!read || read == (size_t)-1) { log_error("READING failed: read %" PRIuSIZE "/%" PRIuSIZE " bytes, %" PRIuSIZE " missing.", orig - size, orig, size); -# if LOGLEVEL <= ll_error - if (size) { - log_info("Got the following:"); - logm_info(buf, orig - size); - } -# endif return (feof(file) ? g1m_error_eof : g1m_error_read); } }