Branch data Line data Source code
1 : : /********************************************************************\
2 : : * escape.c : escape SQL reserved characters *
3 : : * Copyright (C) 2001 Linas Vepstas <linas@linas.org> *
4 : : * *
5 : : * This program is free software; you can redistribute it and/or *
6 : : * modify it under the terms of the GNU General Public License as *
7 : : * published by the Free Software Foundation; either version 2 of *
8 : : * the License, or (at your option) any later version. *
9 : : * *
10 : : * This program is distributed in the hope that it will be useful, *
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 : : * GNU General Public License for more details. *
14 : : * *
15 : : * You should have received a copy of the GNU General Public License*
16 : : * along with this program; if not, contact: *
17 : : * *
18 : : * Free Software Foundation Voice: +1-617-542-5942 *
19 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20 : : * Boston, MA 02110-1301, USA gnu@gnu.org *
21 : : \********************************************************************/
22 : :
23 : : /*
24 : : * FILE:
25 : : * escape.c
26 : : *
27 : : * FUNCTION:
28 : : * Escapes the ' and \ characters in a string
29 : : */
30 : :
31 : : #include <config.h>
32 : : #include <glib.h>
33 : : #include <string.h>
34 : :
35 : : #include "gnc-engine.h"
36 : : #include "escape.h"
37 : :
38 : : static QofLogModule log_module = GNC_MOD_BACKEND;
39 : :
40 : : /* ================================================ */
41 : :
42 : : struct _escape
43 : : {
44 : : /* pointer to memory used for escaping arguments */
45 : : char* escape;
46 : : size_t esc_buflen;
47 : : };
48 : :
49 : : /* ================================================ */
50 : : /* escape single-quote marks and backslashes so that the
51 : : * database SQL parser doesn't puke on the query string
52 : : */
53 : :
54 : : const char*
55 : 0 : sqlEscapeString (sqlEscape* b, const char* str)
56 : : {
57 : : const char* p, *src_head;
58 : : char* dst_tail;
59 : : size_t len, slen;
60 : :
61 : 0 : ENTER ("str = %s", str);
62 : :
63 : 0 : if (!b || !str)
64 : : {
65 : 0 : LEAVE ("(null) args");
66 : 0 : return NULL;
67 : : }
68 : :
69 : : /* if a string is escaped twice, just return the first */
70 : 0 : if (b->escape == str)
71 : : {
72 : 0 : LEAVE ("%s: already escaped", str);
73 : 0 : return str;
74 : : }
75 : :
76 : : /* if nothing to escape, just return */
77 : 0 : len = strlen (str);
78 : 0 : slen = strcspn (str, "\\\'");
79 : 0 : if (len == slen)
80 : : {
81 : 0 : LEAVE ("nothing to escape");
82 : 0 : return str;
83 : : }
84 : :
85 : : /* count to see how much space we'll need */
86 : 0 : p = str + slen + 1;
87 : 0 : while (*p)
88 : : {
89 : 0 : len ++;
90 : 0 : p += 1 + strcspn (p, "\\\'");
91 : : }
92 : :
93 : : /* get more space, if needed */
94 : 0 : if (len >= b->esc_buflen)
95 : : {
96 : 0 : b->escape = static_cast < decltype (b->escape) > (g_realloc (b->escape,
97 : : len + 100));
98 : 0 : b->esc_buflen = len + 100;
99 : : }
100 : :
101 : : /* copy and escape */
102 : 0 : src_head = (char*) str;
103 : 0 : dst_tail = b->escape;
104 : 0 : p = src_head + strcspn (src_head, "\\\'");
105 : 0 : while (*p)
106 : : {
107 : 0 : size_t cp_len = p - src_head;
108 : :
109 : 0 : strncpy (dst_tail, src_head, cp_len);
110 : 0 : dst_tail += cp_len;
111 : 0 : *dst_tail = '\\';
112 : 0 : dst_tail ++;
113 : 0 : *dst_tail = *p;
114 : 0 : dst_tail ++;
115 : :
116 : 0 : src_head = p + 1;
117 : 0 : p = src_head + strcspn (src_head, "\\\'");
118 : : }
119 : 0 : if (p != src_head)
120 : : {
121 : 0 : size_t cp_len = p - src_head;
122 : :
123 : 0 : strncpy (dst_tail, src_head, cp_len);
124 : 0 : dst_tail += cp_len;
125 : : }
126 : 0 : *dst_tail = 0;
127 : :
128 : 0 : LEAVE ("b->escape = %s", b->escape);
129 : 0 : return b->escape;
130 : : }
131 : :
132 : : /* ================================================ */
133 : :
134 : : #define INITIAL_BUFSZ 2000
135 : :
136 : : sqlEscape*
137 : 0 : sqlEscape_new (void)
138 : : {
139 : 0 : sqlEscape* b = g_new (sqlEscape, 1);
140 : :
141 : 0 : b->escape = static_cast < decltype (b->escape) > (g_malloc (INITIAL_BUFSZ));
142 : 0 : b->esc_buflen = INITIAL_BUFSZ;
143 : 0 : return (b);
144 : : }
145 : :
146 : : /* ================================================ */
147 : :
148 : : void
149 : 0 : sqlEscape_destroy (sqlEscape* b)
150 : : {
151 : 0 : ENTER (" ");
152 : 0 : if (!b)
153 : : {
154 : 0 : LEAVE ("b is (null)");
155 : 0 : return;
156 : : }
157 : 0 : g_free (b->escape);
158 : 0 : b->escape = NULL;
159 : 0 : g_free (b);
160 : 0 : LEAVE (" ");
161 : : }
162 : :
163 : : /* ================ END OF FILE ==================== */
|