mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
cc09c00a11
commit
3a4d567892
24
ChangeLog
24
ChangeLog
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/* ================================================ */
|
||||
|
@ -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, "\\\'");
|
||||
|
@ -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 (" ");
|
||||
}
|
||||
|
||||
|
@ -3,3 +3,4 @@ Makefile
|
||||
Makefile.in
|
||||
gnc_test
|
||||
test-db
|
||||
test-escape
|
||||
|
@ -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 \
|
||||
|
@ -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 ();
|
||||
|
62
src/backend/postgres/test/test-escape.c
Normal file
62
src/backend/postgres/test/test-escape.c
Normal 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 ());
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user