cake
/
libcasio
Archived
1
1
Fork 0

More iterators, corrected a buffer overflow.

This commit is contained in:
Thomas Touhey 2018-05-15 12:50:39 +02:00
parent 1a1d119cb2
commit 8f01bf4eaf
No known key found for this signature in database
GPG Key ID: 2ECEB0517AD947FB
16 changed files with 280 additions and 201 deletions

View File

@ -138,15 +138,15 @@ CASIO_EXTERN int CASIO_EXPORT casio_open_usb
int casio__bus, int casio__address));
CASIO_EXTERN int CASIO_EXPORT casio_open_com
OF((casio_link_t **casio__h, unsigned long casio__flags,
const char *casio__path,
const casio_streamattrs_t *casio__attributes));
char const *casio__path,
casio_streamattrs_t const *casio__attributes));
/* Initialize a handle using a custom stream. */
CASIO_EXTERN int CASIO_EXPORT casio_open_link
OF((casio_link_t **casio__h,
unsigned long casio__flags, casio_stream_t *casio__stream,
const casio_streamattrs_t *casio__attributes));
casio_streamattrs_t const *casio__attributes));
/* De-initialize. */

View File

@ -117,7 +117,7 @@ CASIO_EXTERN CASIO_DEPRECATED int CASIO_EXPORT casio_list_mcsfiles
/* Iterate on MCS entries. */
CASIO_EXTERN int CASIO_EXPORT casio_iter_mcsfiles
OF((casio_mcs_t *casio__mcs, casio_iter_t **casio__iter));
OF((casio_iter_t **casio__iter, casio_mcs_t *casio__mcs));
# define casio_next_mcshead(ITER, MCSFILEP) \
(casio_next((ITER), (void **)(casio_mcshead_t **)(MCSFILEP)))

View File

@ -29,7 +29,7 @@
* @return the special bit, for simplicity.
*/
int CASIO_EXPORT casio_bcd_frommcs(casio_bcd_t *bcd, const casio_mcsbcd_t *raw)
int CASIO_EXPORT casio_bcd_frommcs(casio_bcd_t *bcd, casio_mcsbcd_t const *raw)
{
const unsigned char *bytes = raw->casio_mcsbcd_BCDval;

View File

@ -31,18 +31,18 @@ CASIO_LOCAL const char *log_levels[] = {
/* `next_log()`: next log level. */
CASIO_LOCAL int CASIO_EXPORT next_log(const char **cookie, const char **level)
CASIO_LOCAL int CASIO_EXPORT next_log(const char ***cookie, const char **level)
{
if (!*cookie)
if (!**cookie)
return (casio_error_iter);
*level = *cookie++;
*level = *(*cookie)++;
return (0);
}
/* `end_log_iter()`: end the iteration log. */
CASIO_LOCAL int CASIO_EXPORT end_log_iter(const char **cookie)
CASIO_LOCAL int CASIO_EXPORT end_log_iter(const char ***cookie)
{
free(cookie);
return (0);
@ -60,14 +60,14 @@ CASIO_LOCAL casio_iter_funcs_t log_funcs = {
int CASIO_EXPORT casio_iter_log(casio_iter_t **iterp)
{
const char **ptr;
const char ***ptr;
ptr = malloc(sizeof(*ptr));
ptr = malloc(sizeof(char **));
if (!ptr)
return (casio_error_alloc);
*ptr = "none";
return (casio_iter(iterp, ptr, &log_funcs));
*ptr = log_levels;
return (casio_iter(iterp, (void *)ptr, &log_funcs));
}
/* ---

View File

@ -27,7 +27,7 @@
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_iter_mcsfiles(casio_mcs_t *mcs, casio_iter_t **iterp)
int CASIO_EXPORT casio_iter_mcsfiles(casio_iter_t **iterp, casio_mcs_t *mcs)
{
casio_mcs_iter_t *func;
@ -56,7 +56,7 @@ int CASIO_EXPORT casio_list_mcsfiles(casio_mcs_t *mcs,
casio_mcshead_t *head;
int err;
if ((err = casio_iter_mcsfiles(mcs, &iter)))
if ((err = casio_iter_mcsfiles(&iter, mcs)))
return (err);
while (1) {

View File

@ -94,10 +94,13 @@ int CASIO_EXPORT casio_decode_mcsfile_head(casio_mcshead_t *head,
const unsigned char *dirname, const unsigned char *filename,
unsigned long filesize)
{
/* check that we have a head, lol */
if (!head) return (-1);
/* Check that we have a head, lol. */
if (!head)
return (-1);
/* Prepare the head. */
/* prepare the head */
head->casio_mcshead_flags = casio_mcsfor_mcs;
head->casio_mcshead_size = filesize;
head->casio_mcshead_rawtype = raw_type;
@ -107,8 +110,10 @@ int CASIO_EXPORT casio_decode_mcsfile_head(casio_mcshead_t *head,
head->casio_mcshead_group[16] = 0;
strncpy(head->casio_mcshead_dirname, (char*)dirname, 8);
head->casio_mcshead_dirname[8] = 0;
head->casio_mcshead_count = 0;
/* Make the lib abstract types out of this raw information. */
/* make the lib abstract types out of this raw information. */
casio_correct_mcshead(head, 0);
msg((ll_info, "libcasio file type is 0x%08lX", head->casio_mcshead_type));
@ -175,7 +180,8 @@ int CASIO_EXPORT casio_decode_mcsfile(casio_mcsfile_t **handle,
msg((ll_info, "Making a limited buffer of "
"0x%" CASIO_PRIXSIZE " bytes", head.casio_mcshead_size));
err = casio_open_limited(&lbuf, buffer, head.casio_mcshead_size);
if (err) goto fail;
if (err)
goto fail;
/* Call the decode error. */

View File

@ -34,7 +34,7 @@ int CASIO_EXPORT casio_decode_mcs_var(casio_mcsfile_t **handle,
{
int err, num;
unsigned long length = head->casio_mcshead_size;
unsigned char buf[MAX_VAR_NUMBER * sizeof(casio_mcsbcd_t)];
casio_mcsbcd_t buf[MAX_VAR_NUMBER * 2];
const casio_mcsbcd_t *b;
casio_mcsfile_t *h;
int i;
@ -64,7 +64,8 @@ int CASIO_EXPORT casio_decode_mcs_var(casio_mcsfile_t **handle,
/* Copy and decode the variables. */
for (b = (void*)buf, i = 0; i < head->casio_mcshead_count; i++) {
b = (casio_mcsbcd_t const *)buf;
for (i = 0; i < head->casio_mcshead_count; i++) {
casio_bcd_frommcs(&h->casio_mcsfile_vars[i].casio_mcscell_real, b++);
casio_bcd_frommcs(&h->casio_mcsfile_vars[i].casio_mcscell_imgn, b++);
h->casio_mcsfile_vars[i].casio_mcscell_flags = casio_mcscellflag_used;

View File

@ -23,6 +23,10 @@
* casio_correct_mcshead:
* Correct the information.
*
* In order to do that, we'll go from the first specific data to the abstract
* data (which is supposed to be able to represent common things), then from
* the abstract data to the second specific data.
*
* @arg head the MCS head to correct.
* @arg mcsfor the destination platform.
* @return the error code (0 if ok).
@ -31,55 +35,77 @@
int CASIO_EXPORT casio_correct_mcshead(casio_mcshead_t *head,
unsigned long mcsfor)
{
int err; unsigned long inifor;
int err;
unsigned long inifor;
/* Prepare. */
inifor = head->casio_mcshead_flags & casio_mcsfor_mask;
mcsfor = mcsfor & casio_mcsfor_mask;
inifor = casio_mcsfor_mask & head->casio_mcshead_flags;
mcsfor = casio_mcsfor_mask & mcsfor;
/* Check if has already been converted. */
if (inifor == mcsfor)
return (0);
msg((ll_info, "Converting head from info type 0x%02X to 0x%02X",
inifor >> 24, mcsfor >> 24));
/* Check if has already been converted. */
if (inifor == mcsfor) return (0);
/* If we ought to convert from any specific type,
* we have to convert to abstract first. */
switch (inifor) {
case 0: err = 0; break;
case 0:
err = 0;
break;
case casio_mcsfor_mcs:
err = casio_correct_mcshead_from_mcs(head); break;
err = casio_correct_mcshead_from_mcs(head);
break;
case casio_mcsfor_cas40: /* FALLTHRU */
case casio_mcsfor_cas50:
err = casio_correct_mcshead_from_casdata(head); break;
err = casio_correct_mcshead_from_casdata(head);
break;
#if 0 /* TODO */
case casio_mcsfor_cas100:
err = casio_correct_mcshead_from_cas100(head); break;
err = casio_correct_mcshead_from_cas100(head);
break;
#endif
default: err = casio_error_op;
default:
err = casio_error_op;
}
/* If we have encountered an error while doing that,
* we should tell the user about it. */
if (err) return (err);
if (err)
return (err);
head->casio_mcshead_flags &= ~casio_mcsfor_mask;
/* Then we can convert from abstract to specific. */
switch (mcsfor) {
case 0: return (0);
case 0:
return (0);
case casio_mcsfor_mcs:
err = casio_correct_mcshead_to_mcs(head); break;
err = casio_correct_mcshead_to_mcs(head);
break;
case casio_mcsfor_cas40: /* FALLTHRU */
case casio_mcsfor_cas50:
err = casio_correct_mcshead_to_casdata(head); break;
err = casio_correct_mcshead_to_casdata(head);
break;
#if 0 /* TODO */
case casio_mcsfor_cas100:
err = casio_correct_mcshead_to_cas100(head); break;
err = casio_correct_mcshead_to_cas100(head);
break;
#endif
default: err = casio_error_op;
default:
err = casio_error_op;
}
if (err) return (err);
if (err)
return (err);
head->casio_mcshead_flags |= mcsfor;
return (err);
}

View File

@ -33,15 +33,22 @@ int CASIO_EXPORT casio_make_mcsfile(casio_mcsfile_t **h,
int err; casio_mcsfile_t *handle;
/* Allocate the handle. */
*h = casio_alloc(1, sizeof(casio_mcsfile_t)); handle = *h;
if (!handle) return (casio_error_alloc);
*h = casio_alloc(1, sizeof(casio_mcsfile_t));
handle = *h;
if (!handle)
return (casio_error_alloc);
handle->casio_mcsfile_head.casio_mcshead_flags = 0; /* & ~mcsflag_valid */
/* Prepare it. */
err = casio_prepare_mcsfile(handle, rawhead);
if (err) { casio_free(handle); return (err); }
if ((err = casio_prepare_mcsfile(handle, rawhead))) {
casio_free(handle);
return (err);
}
/* Add the flag and return. */
handle->casio_mcsfile_head.casio_mcshead_flags |= casio_mcsflag_alloc;
return (0);
}

View File

@ -320,33 +320,39 @@ int CASIO_EXPORT casio_correct_mcshead_from_mcs(casio_mcshead_t *head)
const struct group_corresp *g;
const struct type_corresp *t;
/* log what we're looking for */
msg((ll_info, "Looking for type with '%.8s' group, '%.8s' name and "
"0x%02X raw type", gname, fname, rawtype));
/* look for group correspondance */
/* Look for group correspondance. */
for (g = mcs_groups; g->types; g++) {
size_t pl = strlen(g->name);
/* check if pattern is there */
/* Check if our pattern is there. */
if (strncmp(g->name, gname, pl))
continue;
if ((g->flags & arg)
&& get_number(&gname[pl], &gid, g->flags & arg_is_num))
continue;
break;
}
if (!g->types)
goto notfound;
/* look for type correspondance */
/* Look for the type correspondance. */
for (t = g->types; t->dirname; t++) {
if (t->rawtype != rawtype)
continue;
/* check if pattern */
/* Check if we match the pattern. */
if (t->name) {
size_t fl = strlen(t->name);
if (strncmp(t->name, fname, fl))
continue;
@ -359,19 +365,24 @@ int CASIO_EXPORT casio_correct_mcshead_from_mcs(casio_mcshead_t *head)
}
break;
}
if (!t->dirname)
goto notfound;
/* fill in info and return */
/* Fill in the info and return. */
head->casio_mcshead_type = t->type;
head->casio_mcshead_id = fid;
return (0);
notfound:
msg((ll_info, "Type with '%s' group, '%s' name and 0x%02x type "
"wasn't recognized.", gname, fname, rawtype));
head->casio_mcshead_type = 0;
head->casio_mcshead_id = 0;
return (1);
}
@ -389,30 +400,40 @@ int CASIO_EXPORT casio_correct_mcshead_to_mcs(casio_mcshead_t *head)
const struct type_corresp *t;
char *gr, *nm;
/* check if there is a type */
if (!head) return (0);
/* Check if there is a type */
if (!head)
return (0);
if (!head->casio_mcshead_type && (!head->casio_mcshead_group[0]
|| !head->casio_mcshead_name[0] || !head->casio_mcshead_dirname[0]))
return (casio_error_op);
/* find the group/type */
/* Find the group/type. */
for (g = mcs_groups; g->types; g++) for (t = g->types; t->dirname; t++) {
/* check if the libcasio type corresponds */
if (t->type != head->casio_mcshead_type) continue;
/* Check if the libcasio type corresponds. */
if (t->type != head->casio_mcshead_type)
continue;
/* Check if id is weighted by major. */
/* check if id is weighted by major */
if (casio_get_id_major(head->casio_mcshead_id)
&& ~t->flags & weight_by_gid) continue;
&& ~t->flags & weight_by_gid)
continue;
/* We have found the entry! */
/* we have found the entry! */
goto found;
}
/* not found... */
/* Not found… */
return (casio_error_op);
found:
/* put the group name */
/* Put the group name. */
gr = (char*)head->casio_mcshead_group;
if (g->flags & arg) {
int grid = casio_get_id_major(head->casio_mcshead_id);
@ -432,10 +453,12 @@ found:
} else
strcpy(gr, g->name);
/* put the directory name */
/* Put the directory name. */
strcpy((char*)head->casio_mcshead_dirname, t->dirname);
/* put the filename */
/* Put the filename. */
nm = (char*)head->casio_mcshead_name;
if (t->flags & arg) {
int namid = casio_get_id_minor(head->casio_mcshead_id);
@ -453,10 +476,12 @@ found:
} else if (t->name)
strcpy(nm, t->name);
/* put the raw type */
/* Put the raw type. */
head->casio_mcshead_rawtype = t->rawtype;
/* no error */
/* No error. */
return (0);
}

View File

@ -58,32 +58,6 @@ BIN " - from " NAME " v" VERSION " (licensed under GPLv2)\n"
* Main argument parsing functions.
* --- */
/**
* put_loglevel:
* Put a loglevel (for listing).
*
* @arg initialized if the list was initialized.
* @arg level the level string.
*/
static void put_loglevel(char **first, const char *level)
{
if (!*first) {
*first = malloc(strlen(level) + 2);
if (!*first) return ;
strcpy(*first + 1, level);
**first = 'F';
return ;
}
if (**first == 'F') {
printf(help_loglevel_init, casio_getlog(), *first + 1);
**first = 'N';
}
printf(", %s", level);
}
/**
* put_help:
* Put the help message on standard output.
@ -91,18 +65,44 @@ static void put_loglevel(char **first, const char *level)
static void put_help(void)
{
char *first;
/* First big part. */
fputs(help_start, stdout);
/* Loglevels. */
first = NULL;
casio_listlog((casio_log_list_t*)&put_loglevel, (void*)&first);
if (first && *first == 'N') fputc('\n', stdout);
free(first);
{
casio_iter_t *iter;
char *first = NULL, *current;
int pos = 0;
if (!casio_iter_log(&iter)) {
while (!casio_next_log(iter, &current)) {
if (!first) {
size_t len = strlen(current) + 1;
first = malloc(len);
if (!first)
break ;
memcpy(first, current, len);
pos++;
continue ;
}
if (pos == 1)
printf(help_loglevel_init, casio_getlog(), first);
printf(", %s", current);
pos++;
}
if (pos > 1)
fputc('\n', stdout);
free(first);
casio_end(iter);
}
}
/* Second big part. */
@ -137,6 +137,7 @@ int parse_args(int ac, char **av, int *num, const char ***paths)
const struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{"log", required_argument, NULL, 'L'},
{NULL, 0, NULL, 0}
};
@ -151,6 +152,9 @@ int parse_args(int ac, char **av, int *num, const char ***paths)
case 'v':
version = 1;
break;
case 'L':
casio_setlog(optarg);
break;
default: switch (optopt) {
default:
fprintf(stderr, "-%c: unknown option.\n", optopt);

View File

@ -27,12 +27,10 @@
* @arg file the MCS file.
*/
static void print_file(void *cookie, const casio_mcshead_t *head)
static void print_file(const casio_mcshead_t *head)
{
const char *password;
(void)cookie;
if (head->casio_mcshead_dirname[0])
printf("%s/", head->casio_mcshead_dirname);
printf("%s: ", head->casio_mcshead_name);
@ -116,5 +114,14 @@ static void print_file(void *cookie, const casio_mcshead_t *head)
void print_files(casio_mcs_t *handle)
{
casio_list_mcsfiles(handle, &print_file, NULL);
casio_iter_t *iter;
casio_mcshead_t *head;
if (casio_iter_mcsfiles(&iter, handle))
return ;
while (!casio_next_mcshead(iter, &head))
print_file(head);
casio_end(iter);
}

View File

@ -200,32 +200,6 @@ static const char help_main_part1[] =
"Type \"" BIN " <subcommand> --help\" for some help about the subcommand.\n"
"Report bugs to " MAINTAINER ".\n";
/**
* put_loglevel:
* Put a loglevel (for listing).
*
* @arg initialized if the list was initialized.
* @arg level the level string.
*/
static void put_loglevel(char **first, const char *level)
{
if (!*first) {
*first = malloc(strlen(level) + 2);
if (!*first) return ;
strcpy(*first + 1, level);
**first = 'F';
return ;
}
if (**first == 'F') {
printf(help_main_loglevel_init, casio_getlog(), *first + 1);
**first = 'N';
}
printf(", %s", level);
}
/**
* put_main_help:
* Put the main help on standard output.
@ -233,18 +207,44 @@ static void put_loglevel(char **first, const char *level)
static void put_main_help(void)
{
char *first;
/* First big part. */
fputs(help_main_part0, stdout);
/* Loglevels. */
first = NULL;
casio_listlog((casio_log_list_t*)&put_loglevel, (void*)&first);
if (first && *first == 'N') fputc('\n', stdout);
free(first);
{
casio_iter_t *iter;
char *first = NULL, *current;
int pos = 0;
if (!casio_iter_log(&iter)) {
while (!casio_next_log(iter, &current)) {
if (!first) {
size_t len = strlen(current) + 1;
first = malloc(len);
if (!first)
break ;
memcpy(first, current, len);
pos++;
continue ;
}
if (pos == 1)
printf(help_main_loglevel_init, casio_getlog(), first);
printf(", %s", current);
pos++;
}
if (pos > 1)
fputc('\n', stdout);
free(first);
casio_end(iter);
}
}
/* Second big part. */

View File

@ -111,33 +111,6 @@ FOOT;
* Put the help message.
* --- */
/**
* put_loglevel:
* Put a loglevel (for listing).
*
* @arg first the first log level.
* @arg level the level string.
*/
static void put_loglevel(char **first, const char *level)
{
if (!*first) {
*first = malloc(strlen(level) + 2);
if (!*first)
return ;
strcpy(*first + 1, level);
**first = 'F';
return ;
}
if (**first == 'F') {
printf(help_log, casio_getlog(), *first + 1);
**first = 'N';
}
printf(", %s", level);
}
/**
* put_help:
* Put the main help message.
@ -145,16 +118,43 @@ static void put_loglevel(char **first, const char *level)
static void put_help(void)
{
char *first;
/* first big part */
fputs(help_main0, stdout);
/* loglevels */
first = NULL;
casio_listlog((casio_log_list_t*)&put_loglevel, (void*)&first);
if (first && *first == 'N') fputc('\n', stdout);
free(first);
/* Loglevels. */
{
casio_iter_t *iter;
char *first = NULL, *current;
int pos = 0;
if (!casio_iter_log(&iter)) {
while (!casio_next_log(iter, &current)) {
if (!first) {
size_t len = strlen(current) + 1;
first = malloc(len);
if (!first)
break ;
memcpy(first, current, len);
pos++;
continue ;
}
if (pos == 1)
printf(help_log, casio_getlog(), first);
printf(", %s", current);
pos++;
}
if (pos > 1)
fputc('\n', stdout);
free(first);
casio_end(iter);
}
}
/* second big part */
puts(help_main1);

View File

@ -39,7 +39,7 @@ int open_link(casio_link_t **link, args_t *args,
if (args->com)
err = casio_open_com(link, flags, args->com, attrs);
else
err = casio_open_usb(link, flags);
err = casio_open_usb(link, flags, -1, -1);
if (err)
return (err);

View File

@ -60,32 +60,6 @@ static const char help_main1[] =
* Main function.
* --- */
/**
* put_loglevel:
* Put a loglevel (for listing).
*
* @arg first the first log level.
* @arg level the level string.
*/
static void put_loglevel(char **first, const char *level)
{
if (!*first) {
*first = malloc(strlen(level) + 2);
if (!*first) return ;
strcpy(*first + 1, level);
**first = 'F';
return ;
}
if (**first == 'F') {
printf(help_log, casio_getlog(), *first + 1);
**first = 'N';
}
printf(", %s", level);
}
/**
* put_help:
* Put the help message.
@ -93,18 +67,47 @@ static void put_loglevel(char **first, const char *level)
static void put_help(void)
{
char *first;
/* Beginning of the help message. */
/* first big part */
fputs(help_main0, stdout);
/* loglevels */
first = NULL;
casio_listlog((casio_log_list_t*)&put_loglevel, (void*)&first);
if (first && *first == 'N') fputc('\n', stdout);
free(first);
/* Loglevels. */
{
casio_iter_t *iter;
char *first = NULL, *current;
int pos = 0;
if (!casio_iter_log(&iter)) {
while (!casio_next_log(iter, &current)) {
if (!first) {
size_t len = strlen(current) + 1;
first = malloc(len);
if (!first)
break ;
memcpy(first, current, len);
pos++;
continue ;
}
if (pos == 1)
printf(help_log, casio_getlog(), first);
printf(", %s", current);
pos++;
}
if (pos > 1)
fputc('\n', stdout);
free(first);
casio_end(iter);
}
}
/* Ending of the help message. */
/* second big part */
fputs(help_main1, stdout);
}