2001-10-11 Dave Peticolas <dave@krondo.com>

* src/test-core/test-stuff.c: allow option of including funky
	characters in random strings

	* src/engine/Transaction.c (xaccTransEqual): add warning strings

	* src/backend/postgres/test/.cvsignore: ignore test-escape

	* src/backend/postgres/test/test-escape: test string escaping

	* src/backend/postgres/test/Makefile.am: add test-escape

	* src/backend/postgres/builder.c (sqlBuild_Where_Str): don't
	escape string twice

	* src/backend/postgres/escape.c (sqlEscapeString): check for
	already-escaped string

	* src/backend/postgres/kvp-sql.c: escape path strings

	* src/backend/file/test/test-xml-transaction.c (test_add_transaction):
	test in reverse order, first orig, then new.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5574 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-10-11 08:22:44 +00:00
parent cc09c00a11
commit 3a4d567892
12 changed files with 277 additions and 51 deletions

View File

@ -1,3 +1,27 @@
2001-10-11 Dave Peticolas <dave@krondo.com>
* src/test-core/test-stuff.c: allow option of including funky
characters in random strings
* src/engine/Transaction.c (xaccTransEqual): add warning strings
* src/backend/postgres/test/.cvsignore: ignore test-escape
* src/backend/postgres/test/test-escape: test string escaping
* src/backend/postgres/test/Makefile.am: add test-escape
* src/backend/postgres/builder.c (sqlBuild_Where_Str): don't
escape string twice
* src/backend/postgres/escape.c (sqlEscapeString): check for
already-escaped string
* src/backend/postgres/kvp-sql.c: escape path strings
* src/backend/file/test/test-xml-transaction.c (test_add_transaction):
test in reverse order, first orig, then new.
2001-10-10 Rob Browning <rlb@defaultvalue.org>
* src/test-core/Makefile.am

View File

@ -296,7 +296,7 @@ test_add_transaction(const char *tag, gpointer globaldata, gpointer data)
xaccTransSetCurrency (trans, gdata->com);
xaccTransCommitEdit (trans);
do_test_args(xaccTransEqual(trans, gdata->trn, TRUE, TRUE),
do_test_args(xaccTransEqual(gdata->trn, trans, TRUE, TRUE),
"gnc_transaction_sixtp_parser_create",
__FILE__, __LINE__,
"%d", gdata->value);

View File

@ -317,7 +317,6 @@ sqlBuild_Where_Str (sqlBuilder *b, const char *tag, const char *val)
{
if (!b || !tag || !val) return;
val = sqlEscapeString (b->escape, val);
switch (b->qtype)
{
case SQL_INSERT:
@ -328,6 +327,8 @@ sqlBuild_Where_Str (sqlBuilder *b, const char *tag, const char *val)
case SQL_UPDATE:
case SQL_SELECT:
case SQL_DELETE:
val = sqlEscapeString (b->escape, val);
if (b->where_need_and) b->pval = stpcpy(b->pval, " AND ");
b->where_need_and = 1;
@ -338,11 +339,9 @@ sqlBuild_Where_Str (sqlBuilder *b, const char *tag, const char *val)
break;
default:
PERR ("mustn't happen");
};
}
/* ================================================ */

View File

@ -53,7 +53,13 @@ sqlEscapeString (sqlEscape *b, const char *str)
const char *p, *src_head;
char *dst_tail;
size_t len, slen;
if (!b || !str) return NULL;
/* if a string is escaped twice, just return the first */
if (b->escape == str)
return str;
/* if nothing to escape, just return */
len = strlen (str);
slen = strcspn (str, "\\\'");

View File

@ -37,6 +37,7 @@
#include <stdlib.h>
#include <string.h>
#include "escape.h"
#include "gnc-engine-util.h"
#include "kvp-sql.h"
#include "PostgresBackend.h"
@ -180,6 +181,7 @@ pgendGetPathCache (PGBackend *be, const char *path_str)
typedef struct store_data_s {
PGBackend *be;
sqlEscape *escape;
int iguid;
int ipath;
char *path;
@ -192,7 +194,6 @@ typedef struct store_data_s {
const GUID *guid;
GList *list;
} u;
} store_data_t;
#include "kvp-autogen.c"
@ -208,7 +209,8 @@ store_cb (const char *key, kvp_value *val, gpointer p)
path_save = cb_data->path;
cb_data->path = g_strjoin ("/", path_save, key, 0);
ipath = pgendGetPathCache (be, cb_data->path);
ipath = pgendGetPathCache (be, sqlEscapeString (cb_data->escape,
cb_data->path));
cb_data->ipath = ipath;
if (ipath)
@ -321,10 +323,14 @@ pgendKVPStore (PGBackend *be, guint32 iguid, kvp_frame *kf)
ENTER (" ");
cb_data.be = be;
cb_data.escape = sqlEscape_new ();
cb_data.iguid = iguid;
cb_data.path = "";
kvp_frame_for_each_slot (kf, store_cb, &cb_data);
sqlEscape_destroy (cb_data.escape);
LEAVE (" ");
}

View File

@ -3,3 +3,4 @@ Makefile
Makefile.in
gnc_test
test-db
test-escape

View File

@ -1,5 +1,6 @@
TESTS = \
test-load-module \
test-escape \
run-tests.sh
TESTS_ENVIRONMENT=\
@ -9,7 +10,8 @@ TESTS_ENVIRONMENT=\
LD_LIBRARY_PATH=${top_srcdir}/src/gnc-module:${top_srcdir}/src/gnc-module/.libs:${top_srcdir}/src/engine:${top_srcdir}/src/engine/.libs
noinst_PROGRAMS = \
test-db
test-db \
test-escape
LDADD = -L${top_srcdir}/src/gnc-module -L${top_srcdir}/src/gnc-module/.libs \
-L${top_srcdir}/src/engine -L${top_srcdir}/src/engine/.libs \

View File

@ -87,6 +87,8 @@ guile_main (int argc, char **argv)
set_max_group_depth (3);
set_max_group_accounts (5);
random_character_include_funky_chars (FALSE);
xaccLogDisable ();
run_test ();

View File

@ -0,0 +1,62 @@
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "escape.h"
#include "test-stuff.h"
static sqlEscape *escape = NULL;
static void
test_escape (const char *s, const char *expected)
{
const char *escaped;
gboolean success;
escaped = sqlEscapeString (escape, s);
if (escaped == expected)
success = TRUE;
else
success = (strcmp (escaped, expected) == 0);
do_test_args (success, "escape test", __FILE__, __LINE__,
"bad escaping: expected %s -> %s, got %s",
s, expected, escaped);
}
int
main (int argc, char *argv[])
{
int i;
random_character_include_funky_chars (TRUE);
escape = sqlEscape_new ();
test_escape (NULL, NULL);
test_escape ("", "");
test_escape ("'", "\\'");
test_escape ("\\", "\\\\");
for (i = 0; i < 200; i++)
{
char *s;
const char *ss;
s = get_random_string ();
ss = sqlEscapeString (escape, s);
sqlEscapeString (escape, ss);
g_free (s);
}
success ("crash test");
sqlEscape_destroy (escape);
print_test_results ();
exit (get_rv ());
}

View File

@ -226,29 +226,78 @@ xaccSplitEqual(const Split *sa, const Split *sb,
gboolean check_txn_splits) {
if(!sa && !sb) return TRUE;
if(!sa) return FALSE;
if(!sb) return FALSE;
if (!sa || !sb)
{
PWARN ("one is NULL");
return FALSE;
}
if(check_guids) {
if(!guid_equal(&(sa->guid), &(sb->guid))) return FALSE;
if(!guid_equal(&(sa->guid), &(sb->guid)))
{
PWARN ("GUIDs differ");
return FALSE;
}
}
/* Since these strings are cached we can just use pointer equality */
if(sa->memo != sb->memo) return FALSE;
if(sa->action != sb->action) return FALSE;
if (sa->memo != sb->memo)
{
PWARN ("memos differ: %s vs %s", sa->memo, sb->memo);
return FALSE;
}
if(kvp_frame_compare(sa->kvp_data, sb->kvp_data) != 0) return FALSE;
if (sa->action != sb->action)
{
PWARN ("actions differ: %s vs %s", sa->action, sb->action);
return FALSE;
}
if(sa->reconciled != sb->reconciled) return FALSE;
if(timespec_cmp(&(sa->date_reconciled),
&(sb->date_reconciled))) return FALSE;
if (kvp_frame_compare(sa->kvp_data, sb->kvp_data) != 0)
{
char *frame_a;
char *frame_b;
if(!gnc_numeric_eq(sa->amount, sb->amount)) return FALSE;
if(!gnc_numeric_eq(sa->value, sb->value)) return FALSE;
frame_a = kvp_frame_to_string (sa->kvp_data);
frame_b = kvp_frame_to_string (sb->kvp_data);
if(!xaccTransEqual(sa->parent, sb->parent,
check_guids,
check_txn_splits)) {
PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
g_free (frame_a);
g_free (frame_b);
return FALSE;
}
if (sa->reconciled != sb->reconciled)
{
PWARN ("reconcile flags differ: %c vs %c", sa->reconciled, sb->reconciled);
return FALSE;
}
if (timespec_cmp(&(sa->date_reconciled),
&(sb->date_reconciled)))
{
PWARN ("reconciled date differs");
return FALSE;
}
if (!gnc_numeric_eq(sa->amount, sb->amount))
{
PWARN ("amount differs");
return FALSE;
}
if (!gnc_numeric_eq(sa->value, sb->value))
{
PWARN ("value differs");
return FALSE;
}
if (!xaccTransEqual(sa->parent, sb->parent, check_guids, check_txn_splits))
{
PWARN ("transactions differ");
return FALSE;
}
@ -800,43 +849,103 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb,
gboolean check_splits) {
if(!ta && !tb) return TRUE;
if(!ta) return FALSE;
if(!tb) return FALSE;
if(!ta || !tb)
{
PWARN ("one is NULL");
return FALSE;
}
if(check_guids) {
if(!guid_equal(&(ta->guid), &(tb->guid))) return FALSE;
if(!guid_equal(&(ta->guid), &(tb->guid)))
{
PWARN ("GUIDs differ");
return FALSE;
}
}
if(!gnc_commodity_equiv(ta->common_currency, tb->common_currency))
{
PWARN ("commodities differ %s vs %s",
gnc_commodity_get_unique_name (ta->common_currency),
gnc_commodity_get_unique_name (tb->common_currency));
return FALSE;
}
if(timespec_cmp(&(ta->date_entered), &(tb->date_entered)))
{
PWARN ("date entered differs");
return FALSE;
}
if(timespec_cmp(&(ta->date_posted), &(tb->date_posted)))
{
PWARN ("date posted differs");
return FALSE;
}
if(timespec_cmp(&(ta->date_entered), &(tb->date_entered))) return FALSE;
if(timespec_cmp(&(ta->date_posted), &(tb->date_posted))) return FALSE;
/* Since we use cached strings, we can just compare pointer
* equality for num and description
*/
if(ta->num != tb->num) return FALSE;
if(ta->description != tb->description) return FALSE;
if(ta->num != tb->num)
{
PWARN ("num differs: %s vs %s", ta->num, tb->num);
return FALSE;
}
if(kvp_frame_compare(ta->kvp_data, tb->kvp_data) != 0) return FALSE;
if(ta->description != tb->description)
{
PWARN ("descriptions differ: %s vs %s", ta->description, tb->description);
return FALSE;
}
if(check_splits) {
if(kvp_frame_compare(ta->kvp_data, tb->kvp_data) != 0)
{
char *frame_a;
char *frame_b;
frame_a = kvp_frame_to_string (ta->kvp_data);
frame_b = kvp_frame_to_string (tb->kvp_data);
PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
g_free (frame_a);
g_free (frame_b);
return FALSE;
}
if (check_splits)
{
GList *sa = ta->splits;
GList *sb = tb->splits;
if(!sa && sb) return FALSE;
if(!sb && sa) return FALSE;
if ((!sa && sb) || (!sb && sa))
{
PWARN ("only one has splits");
return FALSE;
}
if(sa && sb) {
if (sa && sb)
{
/* presume that the splits are in the same order */
while(sa && sb) {
if(!xaccSplitEqual(sa->data, sb->data, check_guids, FALSE))
while (sa && sb)
{
if (!xaccSplitEqual(sa->data, sb->data, check_guids, FALSE))
{
PWARN ("splits differ");
return(FALSE);
}
sa = sa->next;
sb = sb->next;
}
if(sa != NULL) return(FALSE);
if(sb != NULL) return(FALSE);
if ((sa != NULL) || (sb != NULL))
{
PWARN ("different number of splits");
return(FALSE);
}
}
}

View File

@ -202,27 +202,40 @@ get_random_int_in_range(int start, int end)
return start + (int)((double)end * rand() / (RAND_MAX + 1.0));
}
static char random_chars[] =
static char *random_chars = NULL;
static char plain_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"1234567890"
" "
#if 0
" ";
static char funky_chars[] =
",.'\"`~!@#$%^*(){}[]/=?+-_\\|"
"<>&"
"\n\t"
#endif
"";
"\n\t";
static int rcend = 0;
void
random_character_include_funky_chars (gboolean use_funky_chars)
{
g_free (random_chars);
if (use_funky_chars)
random_chars = g_strconcat (plain_chars, funky_chars, NULL);
else
random_chars = g_strdup (plain_chars);
rcend = strlen (random_chars) - 1;
}
gchar
get_random_character(void)
{
static int rcend = 0;
if(!rcend)
{
rcend = strlen(random_chars) - 1;
}
if (!rcend)
random_character_include_funky_chars (FALSE);
return random_chars[get_random_int_in_range(0, rcend)];
}
@ -255,7 +268,8 @@ get_random_string(void)
{
ret[i] = get_random_character();
}
return ret;
return g_strstrip (ret);
}
gint64

View File

@ -120,6 +120,7 @@ void failure_args(
gboolean get_random_boolean(void);
gint get_random_int_in_range(int start, int end);
void random_character_include_funky_chars (gboolean use_funky_chars);
gchar get_random_character(void);
gchar* get_random_string(void);
gint64 get_random_gint64(void);