Commit 4d5e8596 authored by jehan's avatar jehan

add new api to escape/unescape strings to fit into grammar definition (SIP, VCARD)

parent 44ee926f
......@@ -28,6 +28,7 @@ set(HEADER_FILES
port.h
vfs.h
vconnect.h
parser.h
)
if(ENABLE_TESTS_COMPONENT)
list(APPEND HEADER_FILES tester.h)
......
/*
bctoolbox
Copyright (C) 2017 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BCTBX_PARSER_H_
#define BCTBX_PARSER_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* A 256 entries table where each entries defines if character corresponding to its index is allowed or not (value = 0)
* for instance noescape_rules[':'] = 1 means that ':' should not be escaped
*/
typedef unsigned char bctbx_noescape_rules_t[256+1]; /*last entry (BCTBX_NOESCAPE_RULES_USER_INDEX) is reserved for user purpose. Might be usefull to set if array was initialed of not */
#define BCTBX_NOESCAPE_RULES_USER_INDEX (sizeof(bctbx_noescape_rules_t) -1)
/**
* Allocate a new string with unauthorized characters escaped (I.E replaced by % HEX HEX) if any.
* sample:
* bctbx_noescape_rules_t my_rules = {0}; nothing allowed
* bctbx_noescape_rules_add_alfanums(my_rules);
* char * my_escaped_string = bctbx_escape(my_rules,"François");
* expeted result my_escaped_string == Fran%c3%a7ois
* @param buff NULL terminated input buffer.
* @param noescape_rules bctbx_noescape_rules_t to apply for this input buff
* @return a newly allocated null terminated string
*/
BCTBX_PUBLIC char* bctbx_escape(const char* buff, const bctbx_noescape_rules_t noescape_rules);
/**
* Add a list of allowed charaters to a noescape rule.
* @param noescape_rules rule to be modified.
* @param allowed string representing allowed char. Sample: ";-/"
*/
BCTBX_PUBLIC void bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescape_rules, const char *allowed);
/**
* Add a range of allowed charaters to noescape rule. bctbx_noescape_rules_add_range(noescape_rules, '0','9') is the same as bctbx_noescape_rules_add_list(noescape_rules,"0123456789")
* @param noescape_rules rule to be modified.
* @param first allowed char.
* @param last allowed char.
*/
BCTBX_PUBLIC void bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescape_rules, char first, char last);
/**
* Add ['0'..'9'], ['a'..'z'] ['A'..'z'] to no escape rule.
*/
BCTBX_PUBLIC void bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescape_rules);
/**
* Allocate a new string with escaped character (I.E % HEX HEX) replaced by unicode char.
* @param buff NULL terminated input buffer.
* @return a newly allocated null terminated string with unescated values.
*/
BCTBX_PUBLIC char* bctbx_unescaped_string(const char* buff);
/**
*Convert a single input "a" into unscaped output if need.
* a = "%c3%a7" into "ç" with return value = 3
* a = "A" into "A" with return value = 1
* @param a input value
* @param out outbut buffer for conversion
* @return number of byte wrote into out
*/
BCTBX_PUBLIC size_t bctbx_get_char (const char *a, char *out);
#ifdef __cplusplus
}
#endif
#endif /*BCTBX_PARSER_H_*/
......@@ -26,6 +26,7 @@ set(BCTOOLBOX_C_SOURCE_FILES
utils/port.c
vfs.c
vconnect.c
parser.c
)
set(BCTOOLBOX_CXX_SOURCE_FILES containers/map.cc)
......
/*
parser.c
Copyright (C) 2017 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "bctoolbox/port.h"
#include "bctoolbox/parser.h"
#include "bctoolbox/logging.h"
char* bctbx_escape(const char* buff, const bctbx_noescape_rules_t noescapes) {
size_t outbuf_size=strlen(buff);
size_t orig_size=outbuf_size;
char *output_buff=(char*)bctbx_malloc(outbuf_size + 1);
int i;
size_t out_buff_index=0;
for(i=0; buff[i] != '\0'; i++) {
int c = ((unsigned char*)buff)[i];
if (outbuf_size < out_buff_index + 3){
// we will possibly add 3 chars
outbuf_size += MAX(orig_size/2,3);
output_buff = bctbx_realloc(output_buff, outbuf_size + 1);
}
if (noescapes[c] == 1) {
output_buff[out_buff_index++]=c;
} else {
// this will write 3 characters
out_buff_index+=snprintf(output_buff+out_buff_index, outbuf_size +1 - out_buff_index, "%%%02x", c);
}
}
output_buff[out_buff_index]='\0';
return output_buff;
}
void bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescapes, const char *allowed) {
while (*allowed) {
noescapes[(unsigned int) *allowed] = 1;
++allowed;
}
}
void bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescapes, char first, char last) {
memset(noescapes + (unsigned int)first, 1, last-first+1);
}
void bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescapes) {
bctbx_noescape_rules_add_range(noescapes, '0', '9');
bctbx_noescape_rules_add_range(noescapes, 'A', 'Z');
bctbx_noescape_rules_add_range(noescapes, 'a', 'z');
}
static int is_escaped_char(const char *a){
return a[0] == '%' && a[1] != '\0' && a[2] != '\0';
}
size_t bctbx_get_char (const char*a, char*out) {
if (is_escaped_char(a)) {
unsigned int tmp;
sscanf(a+1,"%02x",&tmp);
*out=(char)tmp;
return 3;
} else {
*out=*a;
return 1;
}
}
char* bctbx_unescaped_string(const char* buff) {
char *output_buff=bctbx_malloc(strlen(buff)+1);
size_t i;
size_t out_buff_index=0;
for(i=0; buff[i]!='\0'; out_buff_index++) {
i+=bctbx_get_char(buff+i,output_buff+out_buff_index);
}
output_buff[out_buff_index]='\0';
return output_buff;
}
......@@ -32,6 +32,7 @@ if(BCUNIT_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
bctoolbox_tester.h
containers.cc
port.c
parser.c
)
string(REPLACE ";" " " LINK_FLAGS_STR "${LINK_FLAGS}")
......
......@@ -46,6 +46,7 @@ void bctoolbox_tester_init(void(*ftester_printf)(int level, const char *fmt, va_
bc_tester_init(log_handler,BCTBX_LOG_ERROR, 0,NULL);
bc_tester_add_suite(&containers_test_suite);
bc_tester_add_suite(&utils_test_suite);
bc_tester_add_suite(&parser_test_suite);
}
void bctoolbox_tester_uninit(void) {
......
......@@ -34,6 +34,7 @@ extern "C" {
extern test_suite_t containers_test_suite;
extern test_suite_t utils_test_suite;
extern test_suite_t parser_test_suite;
#ifdef __cplusplus
};
......
/*
bctoolbox
Copyright (C) 2016 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bctoolbox_tester.h"
#include "bctoolbox/parser.h"
static void simple_escaping(void) {
char * my_escaped_string;
bctbx_noescape_rules_t my_rules = {0};
bctbx_noescape_rules_add_alfanums(my_rules);
my_escaped_string = bctbx_escape("François",my_rules);
BC_ASSERT_TRUE(strcmp("Fran%c3%a7ois",my_escaped_string)==0);
bctbx_free(my_escaped_string);
}
static void simple_unescaping(void) {
char * my_unescaped_string;
my_unescaped_string = bctbx_unescaped_string("Fran%c3%a7ois");
BC_ASSERT_TRUE(strcmp("François",my_unescaped_string)==0);
bctbx_free(my_unescaped_string);
}
static test_t container_tests[] = {
TEST_NO_TAG("simple escaping", simple_escaping),
TEST_NO_TAG("simple unescaping", simple_unescaping),
};
test_suite_t parser_test_suite = {"Parsing", NULL, NULL, NULL, NULL,
sizeof(container_tests) / sizeof(container_tests[0]), container_tests};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment