r20382 - gnucash/trunk/src/libqof/qof - Bug #644036: Counter format validation fails on Windows because the number format is I64i there.
Christian Stimming
cstim at code.gnucash.org
Tue Mar 8 06:15:08 EST 2011
Author: cstim
Date: 2011-03-08 06:15:07 -0500 (Tue, 08 Mar 2011)
New Revision: 20382
Trac: http://svn.gnucash.org/trac/changeset/20382
Modified:
gnucash/trunk/src/libqof/qof/qofbook-p.h
gnucash/trunk/src/libqof/qof/qofbook.c
gnucash/trunk/src/libqof/qof/test/test-qof.c
gnucash/trunk/src/libqof/qof/test/test-qofbook.c
Log:
Bug #644036: Counter format validation fails on Windows because the number format is I64i there.
Note: Users will run into a problem when copying a windows file to linux
and vice versa because the counter format will have to be changed on the
other operating system each time.
Modified: gnucash/trunk/src/libqof/qof/qofbook-p.h
===================================================================
--- gnucash/trunk/src/libqof/qof/qofbook-p.h 2011-03-07 19:23:26 UTC (rev 20381)
+++ gnucash/trunk/src/libqof/qof/qofbook-p.h 2011-03-08 11:15:07 UTC (rev 20382)
@@ -61,6 +61,14 @@
#define qof_book_set_guid(book,guid) \
qof_instance_set_guid(QOF_INSTANCE(book), guid)
+/** Validate a counter format string with the given
+ * G_GINT64_FORMAT. Returns an error message if the format string
+ * was invalid, or NULL if it is ok. The caller should free the
+ * error message with g_free.
+ */
+gchar *qof_book_validate_counter_format_internal(const gchar *p,
+ const gchar* gint64_format);
+
/* @} */
/* @} */
/* @} */
Modified: gnucash/trunk/src/libqof/qof/qofbook.c
===================================================================
--- gnucash/trunk/src/libqof/qof/qofbook.c 2011-03-07 19:23:26 UTC (rev 20381)
+++ gnucash/trunk/src/libqof/qof/qofbook.c 2011-03-08 11:15:07 UTC (rev 20382)
@@ -563,8 +563,15 @@
gchar *
qof_book_validate_counter_format(const gchar *p)
{
- const gchar *conv_start, *tmp;
+ return qof_book_validate_counter_format_internal(p, G_GINT64_FORMAT);
+}
+gchar *
+qof_book_validate_counter_format_internal(const gchar *p,
+ const gchar *gint64_format)
+{
+ const gchar *conv_start, *tmp = NULL;
+
/* Validate a counter format. This is a very simple "parser" that
* simply checks for a single gint64 conversion specification,
* allowing all modifiers and flags that printf(3) specifies (except
@@ -597,11 +604,23 @@
/* Skip the % */
p++;
+ /* See whether we have already reached the correct format
+ * specification (e.g. "li" on Unix, "I64i" on Windows). */
+ tmp = strstr(p, gint64_format);
+
/* Skip any number of flag characters */
- while (*p && strchr("#0- +'I", *p)) p++;
+ while (*p && (tmp != p) && strchr("#0- +'I", *p))
+ {
+ p++;
+ tmp = strstr(p, gint64_format);
+ }
/* Skip any number of field width digits */
- while (*p && strchr("0123456789", *p)) p++;
+ while (*p && (tmp != p) && strchr("0123456789", *p))
+ {
+ p++;
+ tmp = strstr(p, gint64_format);
+ }
/* A precision specifier always starts with a dot */
if (*p && *p == '.')
@@ -617,10 +636,10 @@
/* See if the format string starts with the correct format
* specification. */
- tmp = strstr(p, G_GINT64_FORMAT);
+ tmp = strstr(p, gint64_format);
if (tmp == NULL)
{
- return g_strdup_printf("Invalid length modifier and/or conversion specifier ('%.2s'), it should be: " G_GINT64_FORMAT, p);
+ return g_strdup_printf("Invalid length modifier and/or conversion specifier ('%.4s'), it should be: %s", p, gint64_format);
}
else if (tmp != p)
{
@@ -628,7 +647,7 @@
}
/* Skip length modifier / conversion specifier */
- p += strlen(G_GINT64_FORMAT);
+ p += strlen(gint64_format);
/* Skip a suffix of any character except % */
while (*p)
Modified: gnucash/trunk/src/libqof/qof/test/test-qof.c
===================================================================
--- gnucash/trunk/src/libqof/qof/test/test-qof.c 2011-03-07 19:23:26 UTC (rev 20381)
+++ gnucash/trunk/src/libqof/qof/test/test-qof.c 2011-03-08 11:15:07 UTC (rev 20382)
@@ -36,6 +36,7 @@
g_type_init(); /* Initialize the GObject system */
g_test_init ( &argc, &argv, NULL ); /* initialize test program */
qof_log_init_filename_special("/dev/null"); /* Init the log system */
+ g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
test_suite_qofbook();
test_suite_qofinstance();
Modified: gnucash/trunk/src/libqof/qof/test/test-qofbook.c
===================================================================
--- gnucash/trunk/src/libqof/qof/test/test-qofbook.c 2011-03-07 19:23:26 UTC (rev 20381)
+++ gnucash/trunk/src/libqof/qof/test/test-qofbook.c 2011-03-08 11:15:07 UTC (rev 20382)
@@ -23,6 +23,7 @@
#include <string.h>
#include <glib.h>
#include <qof.h>
+#include "qofbook-p.h"
static const gchar *suitename = "/qof/qofbook";
void test_suite_qofbook ( void );
@@ -52,9 +53,70 @@
qof_book_mark_readonly( fixture->book );
g_assert( qof_book_is_readonly( fixture->book ) );
}
+static void
+test_book_validate_counter( void )
+{
+ gchar *r;
+ g_test_bug("644036");
+ /* Test for detection of missing format conversion */
+ r = qof_book_validate_counter_format("This string is missing the conversion specifier");
+ g_assert(r);
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation correctly failed: %s", r);
+ }
+ g_free(r);
+
+ /* Test the usual Linux/Unix G_GINT64_FORMAT */
+ r = qof_book_validate_counter_format_internal("Test - %li", "li");
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation erroneously failed: %s", r);
+ }
+ g_assert(r == NULL);
+ g_free(r);
+
+ /* Test the Windows G_GINT64_FORMAT */
+ r = qof_book_validate_counter_format_internal("Test - %I64i", "I64i");
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation erroneously failed: %s", r);
+ }
+ g_assert(r == NULL);
+ g_free(r);
+
+ /* Test the system's GINT64_FORMAT */
+ r = qof_book_validate_counter_format("Test - %" G_GINT64_FORMAT);
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation erroneously failed: %s", r);
+ }
+ g_assert(r == NULL);
+ g_free(r);
+
+ /* Test an erroneous Windows G_GINT64_FORMAT */
+ r = qof_book_validate_counter_format_internal("Test - %li", "I64i");
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation correctly failed: %s", r);
+ }
+ g_assert(r);
+ g_free(r);
+
+ /* Test an erroneous Linux G_GINT64_FORMAT */
+ r = qof_book_validate_counter_format_internal("Test - %I64i", "li");
+ if (r && g_test_verbose())
+ {
+ g_test_message("Counter format validation correctly failed: %s", r);
+ }
+ g_assert(r);
+ g_free(r);
+}
+
void
test_suite_qofbook ( void )
{
g_test_add( suitename, Fixture, NULL, setup, test_book_readonly, teardown );
+ g_test_add_func( suitename, test_book_validate_counter );
}
More information about the gnucash-changes
mailing list