This commit backports a feature in trunk affecting initreqprep so that display name won't
be encoded improperly. Also includes unit tests for the ast_escape_quoted function.
This patch gives 1.8 a much improved outlook in countries which don't use standard
ASCII characters.
(closes issue ASTERISK-16949)
Reported by: Örn Arnarson
Review: https://reviewboard.asterisk.org/r/1235/
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@322585
65c4cc65-6c06-0410-ace0-
fbb531ad65f3
ast_string_field_set(p, fromname, n);
if (sip_cfg.pedanticsipchecking) {
- ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
+ ast_escape_quoted(n, tmp_n, sizeof(tmp_n));
n = tmp_n;
ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0);
l = tmp_l;
*/
void ast_uri_decode(char *s);
+/*!
+ * \brief Escape characters found in a quoted string.
+ *
+ * \note This function escapes quoted characters based on the 'qdtext' set of
+ * allowed characters from RFC 3261 section 25.1.
+ *
+ * \param string string to be escaped
+ * \param outbuf resulting escaped string
+ * \param buflen size of output buffer
+ * \return a pointer to the escaped string
+ */
+char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
+
static force_inline void ast_slinear_saturated_add(short *input, short *value)
{
int res;
return outbuf;
}
+/*! \brief escapes characters specified for quoted portions of sip messages */
+char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
+{
+ const char *ptr = string;
+ char *out = outbuf;
+ char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
+
+ while (*ptr && out - outbuf < buflen - 1) {
+ if (!(strchr(allow, *ptr))
+ && !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
+ && !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
+ && !((unsigned char) *ptr > 0x7f)) { /* UTF8-nonascii */
+
+ if (out - outbuf >= buflen - 2) {
+ break;
+ }
+ out += sprintf(out, "\\%c", (unsigned char) *ptr);
+ } else {
+ *out = *ptr;
+ out++;
+ }
+ ptr++;
+ }
+
+ if (buflen) {
+ *out = '\0';
+ }
+
+ return outbuf;
+}
+
/*! \brief ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string) */
void ast_uri_decode(char *s)
{
return res;
}
+AST_TEST_DEFINE(quoted_escape_test)
+{
+ int res = AST_TEST_PASS;
+ const char *in = "a\"bcdefg\"hijkl\\mnopqrs tuv\twxyz";
+ char out[256] = { 0 };
+ char small[4] = { 0 };
+ int i;
+
+ static struct {
+ char *buf;
+ const size_t buflen;
+
+ const char *output;
+ } tests[] = {
+ {0, sizeof(out),
+ "a\\\"bcdefg\\\"hijkl\\\\mnopqrs tuv\twxyz"},
+ {0, sizeof(small),
+ "a\\\""},
+ };
+
+ tests[0].buf = out;
+ tests[1].buf = small;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "quoted_escape_test";
+ info->category = "/main/utils/";
+ info->summary = "escape a quoted string";
+ info->description = "Escape a string to be quoted and check the result.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ for (i = 0; i < ARRAY_LEN(tests); i++) {
+ ast_escape_quoted(in, tests[i].buf, tests[i].buflen);
+ if (strcmp(tests[i].output, tests[i].buf)) {
+ ast_test_status_update(test, "ESCAPED DOES NOT MATCH EXPECTED, FAIL\n");
+ ast_test_status_update(test, "original: %s\n", in);
+ ast_test_status_update(test, "expected: %s\n", tests[i].output);
+ ast_test_status_update(test, "result: %s\n", tests[i].buf);
+ res = AST_TEST_FAIL;
+ }
+ }
+
+ return res;
+}
+
AST_TEST_DEFINE(md5_test)
{
static const struct {
static int unload_module(void)
{
AST_TEST_UNREGISTER(uri_encode_decode_test);
+ AST_TEST_UNREGISTER(quoted_escape_test);
AST_TEST_UNREGISTER(md5_test);
AST_TEST_UNREGISTER(sha1_test);
AST_TEST_UNREGISTER(base64_test);
static int load_module(void)
{
AST_TEST_REGISTER(uri_encode_decode_test);
+ AST_TEST_REGISTER(quoted_escape_test);
AST_TEST_REGISTER(md5_test);
AST_TEST_REGISTER(sha1_test);
AST_TEST_REGISTER(base64_test);