[gq-commit] gq/src gq-xml.c,1.2,1.3
Status: Beta
Brought to you by:
sur5r
From: <sta...@us...> - 2003-10-05 13:42:16
|
Update of /cvsroot/gqclient/gq/src In directory sc8-pr-cvs1:/tmp/cvs-serv5246 Modified Files: gq-xml.c Log Message: * UTF-8 safety improvements * Moved the .gq upgrade hack from xmlparse.c to gq-xml.c * Many object types now have constructors and destructors of the form new_<type> and free_<type>. Use them instead of self-allocating and freeing memory as it was done before. Removed all such old style object handling Index: gq-xml.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/gq-xml.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** gq-xml.c 4 Oct 2003 09:45:45 -0000 1.2 --- gq-xml.c 5 Oct 2003 13:42:10 -0000 1.3 *************** *** 29,32 **** --- 29,39 ---- #include <gtk/gtk.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> + #include <stdio.h> + #include <errno.h> + #include <fcntl.h> + #include "gq-xml.h" #include "xmlparse.h" *************** *** 39,43 **** #include "template.h" #include "errorchain.h" ! struct cf_comm { --- 46,50 ---- #include "template.h" #include "errorchain.h" ! #include "common.h" struct cf_comm { *************** *** 50,55 **** struct tagstack_entry *e) { ! e->data = calloc(1, sizeof(struct gq_config)); ! default_config(e->data); } --- 57,62 ---- struct tagstack_entry *e) { ! e->data = new_config(); ! e->free_data = (free_func) free_config; } *************** *** 64,68 **** --- 71,79 ---- } comm->config = e->data; + e->data = NULL; + e->free_data = NULL; + } else { + /* the free callback will clean up */ } } *************** *** 76,80 **** l = strtol(e->cdata, &ep, 10); if ((ep && *ep) || l < 0) { ! XMLhandleError(ctx, _("Non-negative integer CDATA expected ('%s')"), e->tag); return -1; } --- 87,93 ---- l = strtol(e->cdata, &ep, 10); if ((ep && *ep) || l < 0) { ! XMLhandleError(ctx, ! _("Non-negative integer CDATA expected ('%s')"), ! e->tag); return -1; } *************** *** 92,96 **** b = 0; } else { ! XMLhandleError(ctx, _("Boolean CDATA ('true' or 'false') expected ('%s')"), e->tag); return -1; } --- 105,111 ---- b = 0; } else { ! XMLhandleError(ctx, ! _("Boolean CDATA ('true' or 'false') expected ('%s')"), ! e->tag); return -1; } *************** *** 220,238 **** { struct gq_config *c = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF-8 safe */ ! strncpy(c->schemaserver, e->cdata, MAX_SERVERNAME_LEN - 1); } - - - - static void ldapserverS(struct parser_context *ctx, struct tagstack_entry *e) { ! struct ldapserver *server = calloc(1, sizeof(struct ldapserver)); ! init_ldapserver(server); e->data = server; } --- 235,247 ---- { struct gq_config *c = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(c->schemaserver, e->cdata); } static void ldapserverS(struct parser_context *ctx, struct tagstack_entry *e) { ! struct ldapserver *server = new_ldapserver(); e->data = server; + e->free_data = (free_func) free_ldapserver; } *************** *** 246,265 **** GByteArray *o = g_byte_array_new(); b64_decode(o, server->bindpw, strlen(server->bindpw)); ! ! memset(server->bindpw, 0, sizeof(server->bindpw)); ! strncpy(server->bindpw, o->data, MIN(o->len, sizeof(server->bindpw) - 1)); } else if (server->bindpw[0] && server->pwencoding[0]) { XMLhandleError(ctx, _("Unsupported password encoding")); } ! if(c->ldapservers) { ! server = c->ldapservers; ! while(server->next) ! server = server->next; ! server->next = e->data; ! } else { ! c->ldapservers = e->data; ! } e->data = NULL; } --- 255,270 ---- GByteArray *o = g_byte_array_new(); b64_decode(o, server->bindpw, strlen(server->bindpw)); ! ! server->bindpw = g_malloc(o->len + 1); ! strncpy(server->bindpw, o->data, o->len); /* UTF-8 OK */ ! server->bindpw[o->len] = 0; } else if (server->bindpw[0] && server->pwencoding[0]) { XMLhandleError(ctx, _("Unsupported password encoding")); } ! c->servers = g_list_append(c->servers, e->data); ! e->data = NULL; + e->free_data = NULL; } *************** *** 268,274 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->name, e->cdata, sizeof(server->name) - 1); } --- 273,277 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->name, e->cdata); } *************** *** 277,284 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->ldaphost, e->cdata, ! sizeof(server->ldaphost) - 1); } --- 280,284 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->ldaphost, e->cdata); } *************** *** 297,304 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->basedn, e->cdata, ! sizeof(server->basedn) - 1); } --- 297,301 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->basedn, e->cdata); } *************** *** 308,315 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->binddn, e->cdata, ! sizeof(server->binddn) - 1); } --- 305,309 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->binddn, e->cdata); } *************** *** 318,325 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->bindpw, e->cdata, ! sizeof(server->bindpw) - 1); } --- 312,316 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->bindpw, e->cdata); } *************** *** 329,336 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->pwencoding, e->cdata, ! sizeof(server->pwencoding) - 1); } --- 320,324 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->pwencoding, e->cdata); } *************** *** 349,356 **** { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(server->searchattr, e->cdata, ! sizeof(server->searchattr) - 1); } --- 337,341 ---- { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(server->searchattr, e->cdata); } *************** *** 426,431 **** struct tagstack_entry *e) { ! e->data = calloc(1, sizeof(struct gq_filter)); ! e->free_data = free; } --- 411,416 ---- struct tagstack_entry *e) { ! e->data = new_filter(); ! e->free_data = (free_func) free_filter; } *************** *** 447,454 **** { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(filter->name, e->cdata, ! sizeof(filter->name) - 1); } --- 432,436 ---- { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(filter->name, e->cdata); } *************** *** 457,464 **** { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(filter->ldapfilter, e->cdata, ! sizeof(filter->ldapfilter) - 1); } --- 439,443 ---- { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(filter->ldapfilter, e->cdata); } *************** *** 467,474 **** { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(filter->servername, e->cdata, ! sizeof(filter->servername) - 1); } --- 446,450 ---- { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(filter->servername, e->cdata); } *************** *** 477,484 **** { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(filter->basedn, e->cdata, ! sizeof(filter->basedn) - 1); } --- 453,457 ---- { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(filter->basedn, e->cdata); } *************** *** 486,490 **** struct tagstack_entry *e) { ! e->data = calloc(1, sizeof(struct gq_template)); } --- 459,464 ---- struct tagstack_entry *e) { ! e->data = new_template(); ! e->free_data = (free_func) free_template; } *************** *** 494,497 **** --- 468,472 ---- struct gq_config *c = peek_tag(ctx->stack, 1)->data; c->templates = g_list_append(c->templates, e->data); + e->free_data = NULL; } *************** *** 502,509 **** { struct gq_template *t = peek_tag(ctx->stack, 1)->data; ! ! /* FIXME - not UTF8-safe */ ! strncpy(t->name, e->cdata, ! sizeof(t->name) - 1); } --- 477,481 ---- { struct gq_template *t = peek_tag(ctx->stack, 1)->data; ! g_free_and_dup(t->name, e->cdata); } *************** *** 839,843 **** } ! static void XMLwarningHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; --- 811,817 ---- } ! static void XMLwarningHandler(struct parser_context *ctx, ! const char *fmt, ...) ! { va_list args; *************** *** 847,851 **** } ! static void XMLerrorHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; --- 821,827 ---- } ! static void XMLerrorHandler(struct parser_context *ctx, ! const char *fmt, ...) ! { va_list args; *************** *** 855,859 **** } ! static void XMLfatalErrorHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; --- 831,837 ---- } ! static void XMLfatalErrorHandler(struct parser_context *ctx, ! const char *fmt, ...) ! { va_list args; *************** *** 863,867 **** } ! struct gq_config *process_rcfile_XML(int error_context, const char *filename) { xmlSAXHandler *handler = g_malloc0(sizeof(xmlSAXHandler)); int rc; --- 841,1005 ---- } ! static int dot_gq_upgrade_hack(int error_context, const char *filename) ! { ! FILE *fp = fopen(filename, "r"); ! extern int errno; ! int changed = 0; ! ! if (fp) { ! /* nasty heuristics to find out if .gq is "old" (written with ! a gq that does not yet use libxml) or "new". ! ! The way this is done is by checking for an "encoding" in ! the first line of .gq (should be: in the xml declaration, ! actually). This works because the encoding is only there in ! "new" versions of .gq. ! ! The situation does not allow to do it differently: We ! cannot just check for the config-version, because for ! this to work the parser would need to run. ! ! A better way would be to check the encoding when the parser ! sees the xml decl. But libxml seems not to allow for this. ! */ ! ! char firstline[255]; ! fgets(firstline, sizeof(firstline) - 1, fp); ! rewind(fp); ! ! if (strstr(firstline, "encoding=") != NULL ) { ! /* NEW version - everything is OK */ ! fclose(fp); ! return 0; ! } else { ! extern const char *gq_codeset; ! char *cfgbuf; ! GString *newbuf; ! int i; ! struct stat sfile; ! ! /* OLD version */ ! ! /* more nastiness... since this config file was written by a ! pre-UTF-8 version of GQ, it's not going to have <>&'" escaped ! properly... fudge this now: silently rewrite the config ! file on disk, then reopen it for the XML parser */ ! changed = 0; ! stat(filename, &sfile); ! cfgbuf = g_malloc(sfile.st_size + 1); ! fread(cfgbuf, 1, sfile.st_size, fp); ! ! cfgbuf[sfile.st_size] = 0; ! newbuf = g_string_sized_new(sfile.st_size + 128); ! ! /* take care of the XML declaration in the first line... */ ! ! g_string_sprintf(newbuf, ! "<?xml version=\"1.0\" encoding=\"%s\" standalone=\"yes\"?>", ! gq_codeset); ! ! /* skip line 1 in the input buffer */ ! for(i = 0 ; cfgbuf[i] && cfgbuf[i] != '\n' ; i++) ; ! for( ; cfgbuf[i] ; i++) { ! switch(cfgbuf[i]) { ! case '\\': ! /* < and > used to be escaped with a \ */ ! if(cfgbuf[i + 1] == '<') { ! g_string_append(newbuf, "<"); ! changed++; ! i++; ! } ! else if(cfgbuf[i + 1] == '>') { ! g_string_append(newbuf, ">"); ! changed++; ! i++; ! } ! else ! g_string_append_c(newbuf, cfgbuf[i]); ! break; ! ! #if 0 /* no need to escape ' and " at all */ ! case '"': ! /* this wasn't escaped at all */ ! g_string_append(newbuf, """); ! changed++; ! break; ! case '\'': ! /* neither was this */ ! g_string_append(newbuf, "'"); ! changed++; ! break; ! #endif ! case '&': ! #if 0 ! /* if it's not the start of an XML escape, it ! must be an illegal & */ ! if(strncmp(cfgbuf + i + 1, "amp;", 4) && ! strncmp(cfgbuf + i + 1, "lt;", 3) && ! strncmp(cfgbuf + i + 1, "gt;", 3) && ! strncmp(cfgbuf + i + 1, "apos;", 5) && ! strncmp(cfgbuf + i + 1, "quot;", 5)) { ! #endif ! g_string_append(newbuf, "&"); ! changed++; ! #if 0 ! } ! else ! g_string_append_c(newbuf, cfgbuf[i]); ! #endif ! break; ! default: ! g_string_append_c(newbuf, cfgbuf[i]); ! } ! } ! fclose(fp); ! ! if(changed) { ! int fd; ! int rc; ! ! int l = strlen(filename) + 20; ! char *tmp = g_malloc(l); ! snprintf(tmp, l, "%s.tmp", filename); ! ! unlink(tmp); /* provide very minor security */ ! fd = open(tmp, O_CREAT | O_WRONLY, ! sfile.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO) ! ); ! ! if (fd < 0) { ! error_push(error_context, ! _("Could not open temporary configuration file '%1$s': %2$s"), ! tmp, strerror(errno)); ! return -1; ! } ! ! rc = write(fd, newbuf->str, newbuf->len); ! if (rc == newbuf->len) { ! close(fd); ! rename(tmp, filename); ! return 1; ! } ! close(fd); ! error_push(error_context, ! _("Could not write silently upgraded configuration file")); ! return -1; /* fwrite error */ ! } ! ! g_free(cfgbuf); ! g_string_free(newbuf, TRUE); ! } ! return 1; /* silent upgrade done */ ! } ! if (errno != ENOENT) { ! error_push(error_context, ! _("Could not open configuration file '%1$s': %2$s"), ! filename, strerror(errno)); ! } ! return -1; /* failed (fopen) */ ! } ! ! struct gq_config *process_rcfile_XML(int error_context, const char *filename) ! { xmlSAXHandler *handler = g_malloc0(sizeof(xmlSAXHandler)); int rc; *************** *** 875,878 **** --- 1013,1017 ---- handler->warning = (warningSAXFunc) XMLwarningHandler; + dot_gq_upgrade_hack(error_context, filename); rc = XMLparse(config_tags, handler, &comm, filename); *************** *** 888,892 **** #ifdef TEST_MAIN ! int main_test(int argc, char **argv) { struct gq_config *config = NULL; int rc = 0; --- 1027,1032 ---- #ifdef TEST_MAIN ! int main_test(int argc, char **argv) ! { struct gq_config *config = NULL; int rc = 0; |