1 /*
2 parser.c
3 Copyright (C) 2017 Belledonne Communications SARL
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
7 as published by the Free Software Foundation; either version 2
8 of 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, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20
21 #include "bctoolbox/port.h"
22 #include "bctoolbox/parser.h"
23 #include "bctoolbox/logging.h"
24
25
26
bctbx_escape(const char * buff,const bctbx_noescape_rules_t noescapes)27 char* bctbx_escape(const char* buff, const bctbx_noescape_rules_t noescapes) {
28 size_t outbuf_size=strlen(buff);
29 size_t orig_size=outbuf_size;
30 char *output_buff=(char*)bctbx_malloc(outbuf_size + 1);
31 int i;
32 size_t out_buff_index=0;
33
34 for(i=0; buff[i] != '\0'; i++) {
35 int c = ((unsigned char*)buff)[i];
36 if (outbuf_size < out_buff_index + 3){
37 // we will possibly add 3 chars
38 outbuf_size += MAX(orig_size/2,3);
39 output_buff = bctbx_realloc(output_buff, outbuf_size + 1);
40 }
41 if (noescapes[c] == 1) {
42 output_buff[out_buff_index++]=c;
43 } else {
44 // this will write 3 characters
45 out_buff_index+=snprintf(output_buff+out_buff_index, outbuf_size +1 - out_buff_index, "%%%02x", c);
46 }
47 }
48 output_buff[out_buff_index]='\0';
49 return output_buff;
50 }
51
bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescapes,const char * allowed)52 void bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescapes, const char *allowed) {
53 while (*allowed) {
54 noescapes[(unsigned int) *allowed] = 1;
55 ++allowed;
56 }
57 }
58
bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescapes,char first,char last)59 void bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescapes, char first, char last) {
60 memset(noescapes + (unsigned int)first, 1, last-first+1);
61 }
62
bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescapes)63 void bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescapes) {
64 bctbx_noescape_rules_add_range(noescapes, '0', '9');
65 bctbx_noescape_rules_add_range(noescapes, 'A', 'Z');
66 bctbx_noescape_rules_add_range(noescapes, 'a', 'z');
67 }
68
is_escaped_char(const char * a)69 static int is_escaped_char(const char *a){
70 return a[0] == '%' && a[1] != '\0' && a[2] != '\0';
71 }
72
bctbx_get_char(const char * a,char * out)73 size_t bctbx_get_char (const char*a, char*out) {
74 if (is_escaped_char(a)) {
75 unsigned int tmp;
76 sscanf(a+1,"%02x",&tmp);
77 *out=(char)tmp;
78 return 3;
79 } else {
80 *out=*a;
81 return 1;
82 }
83 }
84
bctbx_unescaped_string(const char * buff)85 char* bctbx_unescaped_string(const char* buff) {
86 char *output_buff=bctbx_malloc(strlen(buff)+1);
87 size_t i;
88 size_t out_buff_index=0;
89
90 for(i=0; buff[i]!='\0'; out_buff_index++) {
91 i+=bctbx_get_char(buff+i,output_buff+out_buff_index);
92 }
93 output_buff[out_buff_index]='\0';
94 return output_buff;
95 }
96