diff options
author | Matt Jordan <mjordan@digium.com> | 2015-06-08 13:16:13 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2015-06-08 13:16:13 -0500 |
commit | e29f28e7a5b058ba4a8e7d6edb8514a28fae0ec0 (patch) | |
tree | bfa84b94e391249929dafb0d06d6e356319b5fd9 /main | |
parent | 720251f2b80639324a37b2041997292d97858d39 (diff) | |
parent | f5d5aa67dcdc274770c47b1a801a449fb83c2f79 (diff) |
Merge "AMI: Escape string values." into 13
Diffstat (limited to 'main')
-rw-r--r-- | main/manager_channels.c | 33 | ||||
-rw-r--r-- | main/presencestate.c | 15 | ||||
-rw-r--r-- | main/stasis_channels.c | 10 | ||||
-rw-r--r-- | main/utils.c | 108 |
4 files changed, 155 insertions, 11 deletions
diff --git a/main/manager_channels.c b/main/manager_channels.c index 3aaab92d0..552adc763 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -408,6 +408,7 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( { struct ast_str *out = ast_str_create(1024); int res = 0; + char *caller_name, *connected_name; if (!out) { return NULL; @@ -418,6 +419,9 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( return NULL; } + caller_name = ast_escape_c_alloc(snapshot->caller_name); + connected_name = ast_escape_c_alloc(snapshot->connected_name); + res = ast_str_set(&out, 0, "%sChannel: %s\r\n" "%sChannelState: %u\r\n" @@ -436,9 +440,9 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( prefix, snapshot->state, prefix, ast_state2str(snapshot->state), prefix, S_OR(snapshot->caller_number, "<unknown>"), - prefix, S_OR(snapshot->caller_name, "<unknown>"), + prefix, S_OR(caller_name, "<unknown>"), prefix, S_OR(snapshot->connected_number, "<unknown>"), - prefix, S_OR(snapshot->connected_name, "<unknown>"), + prefix, S_OR(connected_name, "<unknown>"), prefix, snapshot->language, prefix, snapshot->accountcode, prefix, snapshot->context, @@ -448,18 +452,26 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( if (!res) { ast_free(out); + ast_free(caller_name); + ast_free(connected_name); return NULL; } if (snapshot->manager_vars) { struct ast_var_t *var; + char *val; AST_LIST_TRAVERSE(snapshot->manager_vars, var, entries) { + val = ast_escape_c_alloc(var->value); ast_str_append(&out, 0, "%sChanVariable: %s=%s\r\n", prefix, - var->name, var->value); + var->name, S_OR(val, "")); + ast_free(val); } } + ast_free(caller_name); + ast_free(connected_name); + return out; } @@ -556,6 +568,9 @@ static struct ast_manager_event_blob *channel_new_callerid( struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot) { + struct ast_manager_event_blob *res; + char *callerid; + /* No NewCallerid event on cache clear or first event */ if (!old_snapshot || !new_snapshot) { return NULL; @@ -565,11 +580,19 @@ static struct ast_manager_event_blob *channel_new_callerid( return NULL; } - return ast_manager_event_blob_create( + if (!(callerid = ast_escape_c_alloc( + ast_describe_caller_presentation(new_snapshot->caller_pres)))) { + return NULL; + } + + res = ast_manager_event_blob_create( EVENT_FLAG_CALL, "NewCallerid", "CID-CallingPres: %d (%s)\r\n", new_snapshot->caller_pres, - ast_describe_caller_presentation(new_snapshot->caller_pres)); + callerid); + + ast_free(callerid); + return res; } static struct ast_manager_event_blob *channel_new_connected_line( diff --git a/main/presencestate.c b/main/presencestate.c index ab03336e2..207e2aacb 100644 --- a/main/presencestate.c +++ b/main/presencestate.c @@ -393,14 +393,23 @@ int ast_presence_state_engine_init(void) static struct ast_manager_event_blob *presence_state_to_ami(struct stasis_message *msg) { struct ast_presence_state_message *presence_state = stasis_message_data(msg); + struct ast_manager_event_blob *res; - return ast_manager_event_blob_create(EVENT_FLAG_CALL, "PresenceStateChange", + char *subtype = ast_escape_c_alloc(presence_state->subtype); + char *message = ast_escape_c_alloc(presence_state->message); + + res = ast_manager_event_blob_create(EVENT_FLAG_CALL, "PresenceStateChange", "Presentity: %s\r\n" "Status: %s\r\n" "Subtype: %s\r\n" "Message: %s\r\n", presence_state->provider, ast_presence_state2str(presence_state->state), - presence_state->subtype, - presence_state->message); + subtype ?: "", + message ?: ""); + + ast_free(subtype); + ast_free(message); + + return res; } diff --git a/main/stasis_channels.c b/main/stasis_channels.c index ae76c1e84..b8efd407b 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -793,8 +793,12 @@ static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg) struct ast_channel_blob *obj = stasis_message_data(msg); const char *variable = ast_json_string_get(ast_json_object_get(obj->blob, "variable")); - const char *value = - ast_json_string_get(ast_json_object_get(obj->blob, "value")); + RAII_VAR(char *, value, ast_escape_c_alloc( + ast_json_string_get(ast_json_object_get(obj->blob, "value"))), ast_free); + + if (!value) { + return NULL; + } if (obj->snapshot) { channel_event_string = @@ -1713,4 +1717,4 @@ static void remove_dial_masquerade_caller(struct ast_channel *caller) ast_channel_datastore_remove(caller, datastore); ast_datastore_free(datastore); -}
\ No newline at end of file +} diff --git a/main/utils.c b/main/utils.c index d162cccf8..67c391ce2 100644 --- a/main/utils.c +++ b/main/utils.c @@ -1623,6 +1623,114 @@ char *ast_unescape_c(char *src) return ret; } +/* + * Standard escape sequences - Note, '\0' is not included as a valid character + * to escape, but instead is used here as a NULL terminator for the string. + */ +char escape_sequences[] = { + '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\'', '\"', '\?', '\0' +}; + +/* + * Standard escape sequences output map (has to maintain matching order with + * escape_sequences). '\0' is included here as a NULL terminator for the string. + */ +static char escape_sequences_map[] = { + 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"', '?', '\0' +}; + +char* ast_escape(char *dest, const char *s, size_t num, const char *to_escape) +{ + char *p; + + if (!dest || ast_strlen_zero(s)) { + return dest; + } + + if (ast_strlen_zero(to_escape)) { + ast_copy_string(dest, s, num); + return dest; + } + + for (p = dest; *s && num--; ++s, ++p) { + /* If in the list of characters to escape then escape it */ + if (strchr(to_escape, *s)) { + /* + * See if the character to escape is part of the standard escape + * sequences. If so we'll have to use its mapped counterpart + * otherwise just use the current character. + */ + char *c = strchr(escape_sequences, *s); + *p++ = '\\'; + *p = c ? escape_sequences_map[c - escape_sequences] : *s; + } else { + *p = *s; + } + } + + *p = '\0'; + return dest; +} + +char* ast_escape_c(char *dest, const char *s, size_t num) +{ + /* + * Note - This is an optimized version of ast_escape. When looking only + * for escape_sequences a couple of checks used in the generic case can + * be left out thus making it slightly more efficient. + */ + char *p; + + if (!dest || ast_strlen_zero(s)) { + return dest; + } + + for (p = dest; *s && num--; ++s, ++p) { + /* + * See if the character to escape is part of the standard escape + * sequences. If so use its mapped counterpart. + */ + char *c = strchr(escape_sequences, *s); + if (c) { + *p++ = '\\'; + *p = escape_sequences_map[c - escape_sequences]; + } else { + *p = *s; + } + } + + *p = '\0'; + return dest; +} + +static char *escape_alloc(const char *s, size_t *size) +{ + if (!s || !(*size = strlen(s))) { + return NULL; + } + + /* + * The result string needs to be twice the size of the given + * string just in case every character in it needs to be escaped. + */ + *size = *size * 2 + 1; + return ast_calloc(sizeof(char), *size); +} + +char *ast_escape_alloc(const char *s, const char *to_escape) +{ + size_t size = 0; + char *dest = escape_alloc(s, &size); + return ast_escape(dest, s, size, to_escape); +} + +char *ast_escape_c_alloc(const char *s) +{ + size_t size = 0; + char *dest = escape_alloc(s, &size); + return ast_escape_c(dest, s, size); +} + int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap) { int result; |