mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add better handling of corrupt XML data files. Print better error
messages for unknown tags, or mismatched start/end tags. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7717 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
5693b12b80
commit
cf6a6869e4
41
ChangeLog
41
ChangeLog
@ -1,3 +1,44 @@
|
||||
2002-12-23 David Hampton <hampton@employees.org>
|
||||
|
||||
* src/app-file/gnc-file.c: Add missing error message.
|
||||
|
||||
* src/backend/file/sixtp-dom-parsers.c:
|
||||
* src/backend/file/sixtp-stack.c:
|
||||
* src/backend/file/sixtp.c: Better handling of corrupt XML data
|
||||
files. Print better error messages for unknown tags, or
|
||||
mismatched start/end tags.
|
||||
|
||||
|
||||
* src/engine/engine-utilities.scm: Check for errors when trying to
|
||||
open a new session file.
|
||||
|
||||
* src/engine/gw-engine-spec.scm: Added wrappers to access the
|
||||
engine suspend/resume events functions.
|
||||
|
||||
* src/scm/command-line.scm: Suspend engine events when running
|
||||
with the --add-price-quotes flag.
|
||||
|
||||
* src/scm/price-quotes.scm: Add some additional checking.
|
||||
|
||||
|
||||
* src/gnome-utils/dialog-transfer.c: Change logic to multiply by
|
||||
the exchange rate instead of divide. Look for both both forward
|
||||
and reverse currency quotes in the pricedb. Attempt to install
|
||||
currency quotes into the pricedb in a consistent manner. Give the
|
||||
user better feedback on exactly what the exchange rate
|
||||
means. Obsolete the currency "swap" routine. #101450
|
||||
|
||||
* src/gnome-utils/transfer.glade: Give the user better feedback on
|
||||
exactly what the exchange rate means.
|
||||
|
||||
* src/register/ledger-core/split-register-control.c: Remove
|
||||
function call to obolete routine.
|
||||
|
||||
* src/engine/gnc-pricedb.c:
|
||||
* src/engine/gw-engine-spec.scm: Added a new function
|
||||
(gnc_pricedb_lookup_day) to retrieve a price quote from a certain
|
||||
day, not just an exact time.
|
||||
|
||||
2002-12-22 Chris Lyttle <chris@wilddev.net>
|
||||
|
||||
* rpm/gnucash.spec.in: require g-wrap 1.3.4
|
||||
|
@ -819,7 +819,7 @@ dom_tree_generic_parse(xmlNodePtr node, struct dom_tree_handler *handlers,
|
||||
{
|
||||
PERR("gnc_xml_set_data failed");
|
||||
successful = FALSE;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ sixtp_context_run_end_handler(sixtp_parser_context* ctxt)
|
||||
{
|
||||
if(ctxt->top_frame->parser->end_handler)
|
||||
{
|
||||
ctxt->data.parsing_ok =
|
||||
ctxt->data.parsing_ok &=
|
||||
ctxt->top_frame->parser->end_handler(
|
||||
ctxt->top_frame->data_for_children,
|
||||
ctxt->top_frame->data_from_children,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-stack.h"
|
||||
|
||||
#include "gnc-engine-util.h"
|
||||
@ -383,13 +384,6 @@ sixtp_sax_start_handler(void *user_data,
|
||||
gboolean lookup_success = FALSE;
|
||||
sixtp_stack_frame *new_frame = NULL;
|
||||
|
||||
/* don't replace with g_return_if_fail because we don't want to see
|
||||
the critical warnings. We error elsewhere. */
|
||||
if(!pdata->parsing_ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
current_frame = (sixtp_stack_frame *) pdata->stack->data;
|
||||
current_parser = current_frame->parser;
|
||||
|
||||
@ -408,10 +402,10 @@ sixtp_sax_start_handler(void *user_data,
|
||||
(gpointer) &next_parser_tag, (gpointer) &next_parser);
|
||||
if(!lookup_success)
|
||||
{
|
||||
PERR("Tag <%s> not allowed in current context.\n",
|
||||
PERR("Tag <%s> not allowed in current context.",
|
||||
name ? (char *) name : "(null)");
|
||||
pdata->parsing_ok = FALSE;
|
||||
return;
|
||||
next_parser = pdata->bad_xml_parser;
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +423,7 @@ sixtp_sax_start_handler(void *user_data,
|
||||
parent_data_from_children = parent_frame->data_for_children;
|
||||
}
|
||||
|
||||
pdata->parsing_ok =
|
||||
pdata->parsing_ok &=
|
||||
current_frame->parser->before_child(current_frame->data_for_children,
|
||||
current_frame->data_from_children,
|
||||
parent_data_from_children,
|
||||
@ -440,8 +434,6 @@ sixtp_sax_start_handler(void *user_data,
|
||||
name);
|
||||
}
|
||||
|
||||
g_return_if_fail(pdata->parsing_ok);
|
||||
|
||||
/* now allocate the new stack frame and shift to it */
|
||||
new_frame = sixtp_stack_frame_new(next_parser, g_strdup(name));
|
||||
|
||||
@ -452,7 +444,7 @@ sixtp_sax_start_handler(void *user_data,
|
||||
|
||||
if(next_parser->start_handler)
|
||||
{
|
||||
pdata->parsing_ok =
|
||||
pdata->parsing_ok &=
|
||||
next_parser->start_handler(current_frame->data_from_children,
|
||||
current_frame->data_for_children,
|
||||
pdata->global_data,
|
||||
@ -469,19 +461,12 @@ sixtp_sax_characters_handler(void *user_data, const xmlChar *text, int len)
|
||||
sixtp_sax_data *pdata = (sixtp_sax_data *) user_data;
|
||||
sixtp_stack_frame *frame;
|
||||
|
||||
/* don't replace with g_return_if_fail because we don't want to see
|
||||
the critical warnings. We error elsewhere. */
|
||||
if(!pdata->parsing_ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frame = (sixtp_stack_frame *) pdata->stack->data;
|
||||
if(frame->parser->characters_handler)
|
||||
{
|
||||
gpointer result = NULL;
|
||||
|
||||
pdata->parsing_ok =
|
||||
pdata->parsing_ok &=
|
||||
frame->parser->characters_handler(frame->data_from_children,
|
||||
frame->data_for_children,
|
||||
pdata->global_data,
|
||||
@ -514,13 +499,6 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name)
|
||||
sixtp_child_result *child_result_data = NULL;
|
||||
gchar *end_tag = NULL;
|
||||
|
||||
/* don't replace with g_return_if_fail because we don't want to see
|
||||
the critical warnings. We error elsewhere. */
|
||||
if(!pdata->parsing_ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
current_frame = (sixtp_stack_frame *) pdata->stack->data;
|
||||
parent_frame = (sixtp_stack_frame *) pdata->stack->next->data;
|
||||
|
||||
@ -528,15 +506,22 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name)
|
||||
necessary? */
|
||||
if(safe_strcmp(current_frame->tag, name) != 0)
|
||||
{
|
||||
PWARN ("bad closing tag");
|
||||
PWARN ("bad closing tag (start <%s>, end <%s>)", current_frame->tag, name);
|
||||
pdata->parsing_ok = FALSE;
|
||||
return;
|
||||
|
||||
/* See if we're just off by one and try to recover */
|
||||
if(safe_strcmp(parent_frame->tag, name) == 0) {
|
||||
pdata->stack = sixtp_pop_and_destroy_frame(pdata->stack);
|
||||
current_frame = (sixtp_stack_frame *) pdata->stack->data;
|
||||
parent_frame = (sixtp_stack_frame *) pdata->stack->next->data;
|
||||
PWARN ("found matching start <%s> tag up one level", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* tag's OK, proceed. */
|
||||
if(current_frame->parser->end_handler)
|
||||
{
|
||||
pdata->parsing_ok =
|
||||
pdata->parsing_ok &=
|
||||
current_frame->parser->end_handler(current_frame->data_for_children,
|
||||
current_frame->data_from_children,
|
||||
parent_frame->data_from_children,
|
||||
@ -546,8 +531,6 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name)
|
||||
current_frame->tag);
|
||||
}
|
||||
|
||||
g_return_if_fail(pdata->parsing_ok);
|
||||
|
||||
if(current_frame->frame_data)
|
||||
{
|
||||
/* push the result onto the parent's child result list. */
|
||||
@ -595,7 +578,7 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name)
|
||||
parent_data_from_children = parent_frame->data_for_children;
|
||||
}
|
||||
|
||||
pdata->parsing_ok =
|
||||
pdata->parsing_ok &=
|
||||
current_frame->parser->after_child(current_frame->data_for_children,
|
||||
current_frame->data_from_children,
|
||||
parent_data_from_children,
|
||||
@ -688,52 +671,21 @@ sixtp_handle_catastrophe(sixtp_sax_data *sax_data)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
sixtp_parse_file(sixtp *sixtp,
|
||||
const char *filename,
|
||||
gpointer data_for_top_level,
|
||||
gpointer global_data,
|
||||
gpointer *parse_result)
|
||||
static gboolean
|
||||
gnc_bad_xml_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
sixtp_parser_context *ctxt;
|
||||
|
||||
if(!(ctxt = sixtp_context_new(sixtp, global_data, data_for_top_level)))
|
||||
{
|
||||
PERR("sixtp_context_new returned null");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctxt->data.saxParserCtxt = xmlCreateFileParserCtxt( filename );
|
||||
ctxt->data.saxParserCtxt->sax = &ctxt->handler;
|
||||
ctxt->data.saxParserCtxt->userData = &ctxt->data;
|
||||
xmlParseDocument( ctxt->data.saxParserCtxt );
|
||||
//xmlSAXUserParseFile(&ctxt->handler, &ctxt->data, filename);
|
||||
|
||||
if(ctxt->data.parsing_ok)
|
||||
{
|
||||
sixtp_context_run_end_handler(ctxt);
|
||||
if(parse_result)
|
||||
*parse_result = ctxt->top_frame->frame_data;
|
||||
sixtp_context_destroy(ctxt);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(parse_result)
|
||||
*parse_result = NULL;
|
||||
sixtp_handle_catastrophe(&ctxt->data);
|
||||
sixtp_context_destroy(ctxt);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
sixtp_parse_buffer(sixtp *sixtp,
|
||||
char *bufp,
|
||||
int bufsz,
|
||||
gpointer data_for_top_level,
|
||||
gpointer global_data,
|
||||
gpointer *parse_result)
|
||||
static gboolean
|
||||
sixtp_parse_file_common(sixtp *sixtp,
|
||||
xmlParserCtxtPtr xml_context,
|
||||
gpointer data_for_top_level,
|
||||
gpointer global_data,
|
||||
gpointer *parse_result)
|
||||
{
|
||||
sixtp_parser_context *ctxt;
|
||||
|
||||
@ -743,10 +695,12 @@ sixtp_parse_buffer(sixtp *sixtp,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctxt->data.saxParserCtxt = xmlCreateMemoryParserCtxt( bufp, bufsz );
|
||||
ctxt->data.saxParserCtxt = xml_context;
|
||||
ctxt->data.saxParserCtxt->sax = &ctxt->handler;
|
||||
ctxt->data.saxParserCtxt->userData = &ctxt->data;
|
||||
ctxt->data.bad_xml_parser = sixtp_dom_parser_new(gnc_bad_xml_end_handler, NULL, NULL);
|
||||
xmlParseDocument( ctxt->data.saxParserCtxt );
|
||||
//xmlSAXUserParseFile(&ctxt->handler, &ctxt->data, filename);
|
||||
|
||||
sixtp_context_run_end_handler(ctxt);
|
||||
|
||||
@ -761,12 +715,38 @@ sixtp_parse_buffer(sixtp *sixtp,
|
||||
{
|
||||
if(parse_result)
|
||||
*parse_result = NULL;
|
||||
sixtp_handle_catastrophe(&ctxt->data);
|
||||
if (g_slist_length(ctxt->data.stack) > 1)
|
||||
sixtp_handle_catastrophe(&ctxt->data);
|
||||
sixtp_context_destroy(ctxt);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
sixtp_parse_file(sixtp *sixtp,
|
||||
const char *filename,
|
||||
gpointer data_for_top_level,
|
||||
gpointer global_data,
|
||||
gpointer *parse_result)
|
||||
{
|
||||
xmlParserCtxtPtr context = xmlCreateFileParserCtxt( filename );
|
||||
return sixtp_parse_file_common(sixtp, context, data_for_top_level,
|
||||
global_data, parse_result);
|
||||
}
|
||||
|
||||
gboolean
|
||||
sixtp_parse_buffer(sixtp *sixtp,
|
||||
char *bufp,
|
||||
int bufsz,
|
||||
gpointer data_for_top_level,
|
||||
gpointer global_data,
|
||||
gpointer *parse_result)
|
||||
{
|
||||
xmlParserCtxtPtr context = xmlCreateMemoryParserCtxt( bufp, bufsz );
|
||||
return sixtp_parse_file_common(sixtp, context, data_for_top_level,
|
||||
global_data, parse_result);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
static gboolean
|
||||
eat_whitespace(char **cursor)
|
||||
|
@ -151,6 +151,7 @@ typedef struct sixtp_sax_data {
|
||||
GSList *stack;
|
||||
gpointer global_data;
|
||||
xmlParserCtxtPtr saxParserCtxt;
|
||||
sixtp *bad_xml_parser;
|
||||
} sixtp_sax_data;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user