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 ==================== */