summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/res_config_mysql.c364
-rw-r--r--apps/app_fax.c14
-rw-r--r--apps/app_minivm.c8
-rw-r--r--apps/app_queue.c20
-rw-r--r--include/asterisk/json.h35
-rw-r--r--main/aoc.c50
-rw-r--r--main/cel.c4
-rw-r--r--main/json.c146
-rw-r--r--res/res_fax.c12
-rw-r--r--res/stasis/app.c2
-rw-r--r--tests/test_json.c34
11 files changed, 317 insertions, 372 deletions
diff --git a/addons/res_config_mysql.c b/addons/res_config_mysql.c
index be5d00284..1041c1120 100644
--- a/addons/res_config_mysql.c
+++ b/addons/res_config_mysql.c
@@ -126,7 +126,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd,
static char *handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn);
static int require_mysql(const char *database, const char *tablename, va_list ap);
-static int internal_require(const char *database, const char *table, ...) attribute_sentinel;
static struct ast_cli_entry cli_realtime_mysql_status[] = {
AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"),
@@ -165,16 +164,6 @@ static struct mysql_conn *find_database(const char *database, int for_write)
#define release_database(a) ast_mutex_unlock(&(a)->lock)
-static int internal_require(const char *database, const char *table, ...)
-{
- va_list ap;
- int res;
- va_start(ap, table);
- res = require_mysql(database, table, ap);
- va_end(ap);
- return res;
-}
-
static void destroy_table(struct tables *table)
{
struct columns *column;
@@ -600,11 +589,6 @@ static int update_mysql(const char *database, const char *tablename, const char
ESCAPE_STRING(buf, field->value);
ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
- /* If the column length isn't long enough, give a chance to lengthen it. */
- if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
-
while ((field = field->next)) {
/* If the column is not within the table, then skip it */
if (!(column = find_column(table, field->name))) {
@@ -614,11 +598,6 @@ static int update_mysql(const char *database, const char *tablename, const char
ESCAPE_STRING(buf, field->value);
ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf));
-
- /* If the column length isn't long enough, give a chance to lengthen it. */
- if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
ESCAPE_STRING(buf, lookup);
@@ -703,11 +682,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
ESCAPE_STRING(buf, field->value);
ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
first = 0;
-
- /* If the column length isn't long enough, give a chance to lengthen it. */
- if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
first = 1;
@@ -721,11 +695,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
ESCAPE_STRING(buf, field->value);
ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
first = 0;
-
- /* If the column length isn't long enough, give a chance to lengthen it. */
- if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
- internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
release_table(table);
@@ -759,7 +728,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
{
struct mysql_conn *dbh;
- my_ulonglong insertid;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
@@ -792,15 +760,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
- internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-
while ((field = field->next)) {
ESCAPE_STRING(buf, field->value);
- if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
- ast_str_append(&sql, 0, ", `%s`", field->name);
- ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
- }
+ ast_str_append(&sql, 0, ", `%s`", field->name);
+ ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
}
ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
@@ -812,18 +776,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
return -1;
}
- /*!\note The return value is non-portable and may change in future versions. */
- insertid = mysql_insert_id(&dbh->handle);
release_database(dbh);
- ast_debug(1, "MySQL RealTime: row inserted on table: %s, id: %llu\n", table, insertid);
+ ast_debug(1, "MySQL RealTime: row inserted on table: %s\n", table);
- /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
- * An integer greater than zero indicates the number of rows affected
- * Zero indicates that no records were updated
- * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
- */
- return (int)insertid;
+ return 1;
}
static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
@@ -989,105 +946,14 @@ static int unload_mysql(const char *database, const char *tablename)
return cur ? 0 : -1;
}
-static int modify_mysql(const char *database, const char *tablename, struct columns *column, require_type type, int len)
-{
- /*!\note Cannot use ANY of the same scratch space as is used in other functions, as this one is interspersed. */
- struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *escbuf = ast_str_thread_get(&modify2_buf, 100);
- struct ast_str *typestr = ast_str_thread_get(&modify3_buf, 30);
- int waschar = strncasecmp(column->type, "char", 4) == 0 ? 1 : 0;
- int wasvarchar = strncasecmp(column->type, "varchar", 7) == 0 ? 1 : 0;
- int res = 0;
- struct mysql_conn *dbh;
-
- if (!(dbh = find_database(database, 1))) {
- return -1;
- }
-
- do {
- if (type == RQ_CHAR || waschar || wasvarchar) {
- if (wasvarchar) {
- ast_str_set(&typestr, 0, "VARCHAR(%d)", len);
- } else {
- ast_str_set(&typestr, 0, "CHAR(%d)", len);
- }
- } else if (type == RQ_UINTEGER1) {
- ast_str_set(&typestr, 0, "tinyint(3) unsigned");
- } else if (type == RQ_INTEGER1) {
- ast_str_set(&typestr, 0, "tinyint(4)");
- } else if (type == RQ_UINTEGER2) {
- ast_str_set(&typestr, 0, "smallint(5) unsigned");
- } else if (type == RQ_INTEGER2) {
- ast_str_set(&typestr, 0, "smallint(6)");
- } else if (type == RQ_UINTEGER3) {
- ast_str_set(&typestr, 0, "mediumint(8) unsigned");
- } else if (type == RQ_INTEGER3) {
- ast_str_set(&typestr, 0, "mediumint(8)");
- } else if (type == RQ_UINTEGER4) {
- ast_str_set(&typestr, 0, "int(10) unsigned");
- } else if (type == RQ_INTEGER4) {
- ast_str_set(&typestr, 0, "int(11)");
- } else if (type == RQ_UINTEGER8) {
- ast_str_set(&typestr, 0, "bigint(19) unsigned");
- } else if (type == RQ_INTEGER8) {
- ast_str_set(&typestr, 0, "bigint(20)");
- } else if (type == RQ_DATETIME) {
- ast_str_set(&typestr, 0, "datetime");
- } else if (type == RQ_DATE) {
- ast_str_set(&typestr, 0, "date");
- } else if (type == RQ_FLOAT) {
- ast_str_set(&typestr, 0, "FLOAT(%d,2)", len);
- } else {
- ast_log(LOG_ERROR, "Unknown type (should NEVER happen)\n");
- res = -1;
- break;
- }
- ast_str_set(&sql, 0, "ALTER TABLE %s MODIFY `%s` %s", tablename, column->name, ast_str_buffer(typestr));
- if (!column->null) {
- ast_str_append(&sql, 0, " NOT NULL");
- }
- if (!ast_strlen_zero(column->dflt)) {
- ESCAPE_STRING(escbuf, column->dflt);
- ast_str_append(&sql, 0, " DEFAULT '%s'", ast_str_buffer(escbuf));
- }
-
- if (!mysql_reconnect(dbh)) {
- ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
- res = -1;
- break;
- }
-
- /* Execution. */
- if (mysql_real_query(&dbh->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
- ast_log(LOG_WARNING, "MySQL RealTime: Failed to modify database: %s\n", mysql_error(&dbh->handle));
- ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
- res = -1;
- }
- } while (0);
-
- release_database(dbh);
- return res;
-}
-
-#define PICK_WHICH_ALTER_ACTION(stringtype) \
- if (table->database->requirements == RQ_WARN) { \
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
- "the required data length: %d (detected stringtype)\n", \
- tablename, database, column->name, size); \
- res = -1; \
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { \
- table_altered = 1; \
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { \
- table_altered = 1; \
- } else { \
- res = -1; \
- }
-
static int require_mysql(const char *database, const char *tablename, va_list ap)
{
struct columns *column;
struct tables *table = find_table(database, tablename);
char *elm;
- int type, size, res = 0, table_altered = 0;
+ int type;
+ int size;
+ int res = 0;
if (!table) {
ast_log(LOG_WARNING, "Table %s not found in database. This table should exist if you're using realtime.\n", tablename);
@@ -1097,55 +963,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
while ((elm = va_arg(ap, char *))) {
type = va_arg(ap, require_type);
size = va_arg(ap, int);
+
AST_LIST_TRAVERSE(&table->columns, column, list) {
if (strcmp(column->name, elm) == 0) {
/* Char can hold anything, as long as it is large enough */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
if ((size > column->len) && column->len != -1) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
- res = -1;
- } else if (modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
+ res = -1;
}
} else if (strcasestr(column->type, "unsigned")) {
if (!ast_rq_is_int(type)) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
- database, tablename, column->name, column->type,
- type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
- type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+ database, tablename, column->name, column->type,
+ type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+ type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
+ res = -1;
} else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_UINTEGER1) {
- PICK_WHICH_ALTER_ACTION(unsigned tinyint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) {
- PICK_WHICH_ALTER_ACTION(unsigned smallint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3) {
- PICK_WHICH_ALTER_ACTION(unsigned mediumint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4) {
- PICK_WHICH_ALTER_ACTION(unsigned int)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1153,45 +1018,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_UINTEGER8) {
- PICK_WHICH_ALTER_ACTION(unsigned bigint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
}
} else if (strcasestr(column->type, "int")) {
if (!ast_rq_is_int(type)) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
- database, tablename, column->name, column->type,
- type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
- type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
- "to get a life, rather than writing silly error messages");
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+ database, tablename, column->name, column->type,
+ type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+ type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
+ "to get a life, rather than writing silly error messages");
+ res = -1;
} else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_INTEGER1) {
- PICK_WHICH_ALTER_ACTION(tinyint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) {
- PICK_WHICH_ALTER_ACTION(smallint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_INTEGER3) {
- PICK_WHICH_ALTER_ACTION(mediumint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_INTEGER4) {
- PICK_WHICH_ALTER_ACTION(int)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1199,137 +1071,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_INTEGER8) {
- PICK_WHICH_ALTER_ACTION(bigint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
}
} else if (strncmp(column->type, "float", 5) == 0) {
if (!ast_rq_is_int(type) && type != RQ_FLOAT) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+ res = -1;
}
} else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) {
if (type != RQ_DATETIME) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+ res = -1;
}
} else if (strncmp(column->type, "date", 4) == 0) {
if (type != RQ_DATE) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
- }
- } else { /* Other, possibly unsupported types? */
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
}
+ } else { /* Other, possibly unsupported types? */
+ ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+ res = -1;
}
break;
}
}
if (!column) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
- } else {
- struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *fieldtype = ast_str_thread_get(&modify3_buf, 16);
-
- if (table->database->requirements == RQ_CREATECHAR || type == RQ_CHAR) {
- ast_str_set(&fieldtype, 0, "CHAR(%d)", size);
- } else if (type == RQ_UINTEGER1 || type == RQ_UINTEGER2 || type == RQ_UINTEGER3 || type == RQ_UINTEGER4 || type == RQ_UINTEGER8) {
- if (type == RQ_UINTEGER1) {
- ast_str_set(&fieldtype, 0, "TINYINT(3) UNSIGNED");
- } else if (type == RQ_UINTEGER2) {
- ast_str_set(&fieldtype, 0, "SMALLINT(5) UNSIGNED");
- } else if (type == RQ_UINTEGER3) {
- ast_str_set(&fieldtype, 0, "MEDIUMINT(8) UNSIGNED");
- } else if (type == RQ_UINTEGER4) {
- ast_str_set(&fieldtype, 0, "INT(10) UNSIGNED");
- } else if (type == RQ_UINTEGER8) {
- ast_str_set(&fieldtype, 0, "BIGINT(20) UNSIGNED");
- } else {
- ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to squash Tokyo.\n");
- continue;
- }
- } else if (ast_rq_is_int(type)) {
- if (type == RQ_INTEGER1) {
- ast_str_set(&fieldtype, 0, "TINYINT(3)");
- } else if (type == RQ_INTEGER2) {
- ast_str_set(&fieldtype, 0, "SMALLINT(5)");
- } else if (type == RQ_INTEGER3) {
- ast_str_set(&fieldtype, 0, "MEDIUMINT(8)");
- } else if (type == RQ_INTEGER4) {
- ast_str_set(&fieldtype, 0, "INT(10)");
- } else if (type == RQ_INTEGER8) {
- ast_str_set(&fieldtype, 0, "BIGINT(20)");
- } else {
- ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to eat Cincinnati.\n");
- continue;
- }
- } else if (type == RQ_FLOAT) {
- ast_str_set(&fieldtype, 0, "FLOAT");
- } else if (type == RQ_DATE) {
- ast_str_set(&fieldtype, 0, "DATE");
- } else if (type == RQ_DATETIME) {
- ast_str_set(&fieldtype, 0, "DATETIME");
- } else {
- continue;
- }
- ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, ast_str_buffer(fieldtype));
-
- ast_mutex_lock(&table->database->lock);
- if (!mysql_reconnect(table->database)) {
- ast_mutex_unlock(&table->database->lock);
- ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
- continue;
- }
-
- /* Execution. */
- if (mysql_real_query(&table->database->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
- ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
- ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
- ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&table->database->handle));
- } else {
- table_altered = 1;
- }
- }
+ ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
}
}
release_table(table);
- /* If we altered the table, we must refresh the cache */
- if (table_altered) {
- unload_mysql(database, tablename);
- release_table(find_table(database, tablename));
- }
return res;
}
diff --git a/apps/app_fax.c b/apps/app_fax.c
index 88aa6ad1a..e2a7c2a4c 100644
--- a/apps/app_fax.c
+++ b/apps/app_fax.c
@@ -262,13 +262,13 @@ static void phase_e_handler(t30_state_t *f, void *user_data, int result)
}
ast_json_ref(json_filenames);
json_object = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: i, s: o}",
- "type", s->direction ? "send" : "receive",
- "remote_station_id", far_ident,
- "local_station_id", local_ident,
- "fax_pages", pages_transferred,
- "fax_resolution", stat.y_resolution,
- "fax_bitrate", stat.bit_rate,
- "filenames", json_filenames);
+ "type", s->direction ? "send" : "receive",
+ "remote_station_id", AST_JSON_UTF8_VALIDATE(far_ident),
+ "local_station_id", AST_JSON_UTF8_VALIDATE(local_ident),
+ "fax_pages", pages_transferred,
+ "fax_resolution", stat.y_resolution,
+ "fax_bitrate", stat.bit_rate,
+ "filenames", json_filenames);
message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(s->chan), ast_channel_fax_type(), json_object);
if (!message) {
return;
diff --git a/apps/app_minivm.c b/apps/app_minivm.c
index fb7c22aa4..789a48aab 100644
--- a/apps/app_minivm.c
+++ b/apps/app_minivm.c
@@ -1853,10 +1853,10 @@ static int notify_new_message(struct ast_channel *chan, const char *templatename
}
mwi_state->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
- json_object = ast_json_pack("{s: s, s: s}",
- "Event", "MiniVoiceMail"
- "Action", "SentNotification",
- "Counter", counter);
+ json_object = ast_json_pack("{s: s, s: s, s: s}",
+ "Event", "MiniVoiceMail",
+ "Action", "SentNotification",
+ "Counter", counter ?: "");
if (!json_object) {
goto notify_cleanup;
}
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 45b5683ed..0cc3b2685 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -5616,12 +5616,12 @@ static void send_agent_complete(const char *queuename, struct ast_channel_snapsh
}
blob = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: s}",
- "Queue", queuename,
- "Interface", member->interface,
- "MemberName", member->membername,
- "HoldTime", (long)(callstart - holdstart),
- "TalkTime", (long)(time(NULL) - callstart),
- "Reason", reason);
+ "Queue", queuename,
+ "Interface", member->interface,
+ "MemberName", member->membername,
+ "HoldTime", (long)(callstart - holdstart),
+ "TalkTime", (long)(time(NULL) - callstart),
+ "Reason", reason ?: "");
queue_publish_multi_channel_snapshot_blob(ast_queue_topic(queuename), caller, peer,
queue_agent_complete_type(), blob);
@@ -7199,12 +7199,10 @@ static void set_queue_member_pause(struct call_queue *q, struct member *mem, con
}
mem->paused = paused;
- if (paused) {
- if (!ast_strlen_zero(reason)) {
- ast_copy_string(mem->reason_paused, reason, sizeof(mem->reason_paused));
- }
+ if (paused && !ast_strlen_zero(reason)) {
+ ast_copy_string(mem->reason_paused, reason, sizeof(mem->reason_paused));
} else {
- ast_copy_string(mem->reason_paused, "", sizeof(mem->reason_paused));
+ mem->reason_paused[0] = '\0';
}
ast_devstate_changed(mem->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
diff --git a/include/asterisk/json.h b/include/asterisk/json.h
index 28ebfbd51..cfd9a2997 100644
--- a/include/asterisk/json.h
+++ b/include/asterisk/json.h
@@ -217,6 +217,41 @@ const char *ast_json_typename(enum ast_json_type type);
/*!@{*/
/*!
+ * \brief Check the string of the given length for UTF-8 format.
+ * \since 13.12.0
+ *
+ * \param str String to check.
+ * \param len Length of string to check.
+ *
+ * \retval 0 if not UTF-8 encoded or str is NULL.
+ * \retval 1 if UTF-8 encoded.
+ */
+int ast_json_utf8_check_len(const char *str, size_t len);
+
+/*!
+ * \brief Check the nul terminated string for UTF-8 format.
+ * \since 13.12.0
+ *
+ * \param str String to check.
+ *
+ * \retval 0 if not UTF-8 encoded or str is NULL.
+ * \retval 1 if UTF-8 encoded.
+ */
+int ast_json_utf8_check(const char *str);
+
+/*!
+ * \brief Check str for UTF-8 and replace with an empty string if fails the check.
+ *
+ * \note The convenience macro is normally used with ast_json_pack()
+ * or a function wrapper that calls ast_json_vpack().
+ */
+#define AST_JSON_UTF8_VALIDATE(str) (ast_json_utf8_check(str) ? (str) : "")
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
* \brief Get the JSON true value.
* \since 12.0.0
*
diff --git a/main/aoc.c b/main/aoc.c
index 4ab931536..ba151d760 100644
--- a/main/aoc.c
+++ b/main/aoc.c
@@ -1656,8 +1656,10 @@ static struct ast_json *units_to_json(const struct ast_aoc_decoded *decoded)
static struct ast_json *currency_to_json(const char *name, int cost,
enum ast_aoc_currency_multiplier mult)
{
- return ast_json_pack("{s:s, s:i, s:s}", "Name", name,
- "Cost", cost, "Multiplier", aoc_multiplier_str(mult));
+ return ast_json_pack("{s:s, s:i, s:s}",
+ "Name", AST_JSON_UTF8_VALIDATE(name),
+ "Cost", cost,
+ "Multiplier", aoc_multiplier_str(mult));
}
static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
@@ -1667,8 +1669,8 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
if (decoded->charge_type != AST_AOC_CHARGE_CURRENCY &&
decoded->charge_type != AST_AOC_CHARGE_UNIT) {
- return ast_json_pack("{s:s}", "Type",
- aoc_charge_type_str(decoded->charge_type));
+ return ast_json_pack("{s:s}",
+ "Type", aoc_charge_type_str(decoded->charge_type));
}
if (decoded->charge_type == AST_AOC_CHARGE_CURRENCY) {
@@ -1680,8 +1682,7 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
obj = units_to_json(decoded);
}
- return ast_json_pack(
- "{s:s, s:s, s:s, s:o}",
+ return ast_json_pack("{s:s, s:s, s:s, s:o}",
"Type", aoc_charge_type_str(decoded->charge_type),
"BillingID", aoc_billingid_str(decoded->billing_id),
"TotalType", aoc_type_of_totaling_str(decoded->total_type),
@@ -1692,13 +1693,11 @@ static struct ast_json *association_to_json(const struct ast_aoc_decoded *decode
{
switch (decoded->charging_association.charging_type) {
case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
- return ast_json_pack(
- "{s:s, s:i}",
- "Number", decoded->charging_association.charge.number.number,
+ return ast_json_pack("{s:s, s:i}",
+ "Number", AST_JSON_UTF8_VALIDATE(decoded->charging_association.charge.number.number),
"Plan", decoded->charging_association.charge.number.plan);
case AST_AOC_CHARGING_ASSOCIATION_ID:
- return ast_json_pack(
- "{s:i}", "ID", decoded->charging_association.charge.id);
+ return ast_json_pack("{s:i}", "ID", decoded->charging_association.charge.id);
case AST_AOC_CHARGING_ASSOCIATION_NA:
default:
return ast_json_null();
@@ -1740,22 +1739,22 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.duration.amount,
decoded->aoc_s_entries[i].rate.duration.multiplier);
- time = ast_json_pack(
- "{s:i, s:s}",
+ time = ast_json_pack("{s:i, s:i}",
"Length", decoded->aoc_s_entries[i].rate.duration.time,
"Scale", decoded->aoc_s_entries[i].rate.duration.time_scale);
if (decoded->aoc_s_entries[i].rate.duration.granularity_time) {
- granularity = ast_json_pack(
- "{s:i, s:s}",
+ granularity = ast_json_pack("{s:i, s:i}",
"Length", decoded->aoc_s_entries[i].rate.duration.granularity_time,
"Scale", decoded->aoc_s_entries[i].rate.duration.granularity_time_scale);
}
- type = ast_json_pack("{s:o, s:s, s:o, s:o}", "Currency", ast_json_ref(currency), "ChargingType",
- decoded->aoc_s_entries[i].rate.duration.charging_type ?
- "StepFunction" : "ContinuousCharging", "Time", ast_json_ref(time),
- "Granularity", granularity ? ast_json_ref(granularity) : ast_json_ref(ast_json_null()));
+ type = ast_json_pack("{s:o, s:s, s:o, s:o}",
+ "Currency", ast_json_ref(currency),
+ "ChargingType", decoded->aoc_s_entries[i].rate.duration.charging_type
+ ? "StepFunction" : "ContinuousCharging",
+ "Time", ast_json_ref(time),
+ "Granularity", granularity ? ast_json_ref(granularity) : ast_json_null());
break;
}
@@ -1773,21 +1772,22 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.volume.amount,
decoded->aoc_s_entries[i].rate.volume.multiplier);
- type = ast_json_pack(
- "{s:s, s:o}", "Unit", aoc_volume_unit_str(
+ type = ast_json_pack("{s:s, s:o}",
+ "Unit", aoc_volume_unit_str(
decoded->aoc_s_entries[i].rate.volume.volume_unit),
"Currency", ast_json_ref(currency));
break;
case AST_AOC_RATE_TYPE_SPECIAL_CODE:
- type = ast_json_pack("{s:i}", "SpecialCode",
- decoded->aoc_s_entries[i].rate.special_code);
+ type = ast_json_pack("{s:i}",
+ "SpecialCode", decoded->aoc_s_entries[i].rate.special_code);
break;
default:
break;
}
- rate = ast_json_pack("{s:s, s:o}", "Chargeable", charge_item,
- aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), ast_json_ref(type));
+ rate = ast_json_pack("{s:s, s:o}",
+ "Chargeable", charge_item,
+ aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), ast_json_ref(type));
if (ast_json_array_append(rates, rate)) {
break;
}
diff --git a/main/cel.c b/main/cel.c
index 4abaac7c8..0cdf1be00 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -1237,10 +1237,10 @@ static void cel_parking_cb(
if (parked_payload->retriever) {
extra = ast_json_pack("{s: s, s: s}",
- "reason", reason,
+ "reason", reason ?: "",
"retriever", parked_payload->retriever->name);
} else {
- extra = ast_json_pack("{s: s}", "reason", reason);
+ extra = ast_json_pack("{s: s}", "reason", reason ?: "");
}
if (extra) {
diff --git a/main/json.c b/main/json.c
index 35e6f16ce..9f42f0adb 100644
--- a/main/json.c
+++ b/main/json.c
@@ -269,6 +269,127 @@ const char *ast_json_typename(enum ast_json_type type)
return "?";
}
+/* Ported from libjansson utf.c:utf8_check_first() */
+static size_t json_utf8_check_first(char byte)
+{
+ unsigned char ch = (unsigned char) byte;
+
+ if (ch < 0x80) {
+ return 1;
+ }
+
+ if (0x80 <= ch && ch <= 0xBF) {
+ /* second, third or fourth byte of a multi-byte
+ sequence, i.e. a "continuation byte" */
+ return 0;
+ } else if (ch == 0xC0 || ch == 0xC1) {
+ /* overlong encoding of an ASCII byte */
+ return 0;
+ } else if (0xC2 <= ch && ch <= 0xDF) {
+ /* 2-byte sequence */
+ return 2;
+ } else if (0xE0 <= ch && ch <= 0xEF) {
+ /* 3-byte sequence */
+ return 3;
+ } else if (0xF0 <= ch && ch <= 0xF4) {
+ /* 4-byte sequence */
+ return 4;
+ } else { /* ch >= 0xF5 */
+ /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
+ UTF-8 */
+ return 0;
+ }
+}
+
+/* Ported from libjansson utf.c:utf8_check_full() */
+static size_t json_utf8_check_full(const char *str, size_t len)
+{
+ size_t pos;
+ int32_t value;
+ unsigned char ch = (unsigned char) str[0];
+
+ if (len == 2) {
+ value = ch & 0x1F;
+ } else if (len == 3) {
+ value = ch & 0xF;
+ } else if (len == 4) {
+ value = ch & 0x7;
+ } else {
+ return 0;
+ }
+
+ for (pos = 1; pos < len; ++pos) {
+ ch = (unsigned char) str[pos];
+ if (ch < 0x80 || ch > 0xBF) {
+ /* not a continuation byte */
+ return 0;
+ }
+
+ value = (value << 6) + (ch & 0x3F);
+ }
+
+ if (value > 0x10FFFF) {
+ /* not in Unicode range */
+ return 0;
+ } else if (0xD800 <= value && value <= 0xDFFF) {
+ /* invalid code point (UTF-16 surrogate halves) */
+ return 0;
+ } else if ((len == 2 && value < 0x80)
+ || (len == 3 && value < 0x800)
+ || (len == 4 && value < 0x10000)) {
+ /* overlong encoding */
+ return 0;
+ }
+
+ return 1;
+}
+
+int ast_json_utf8_check_len(const char *str, size_t len)
+{
+ size_t pos;
+ size_t count;
+ int res = 1;
+
+ if (!str) {
+ return 0;
+ }
+
+ /*
+ * Since the json library does not make the check function
+ * public we recreate/copy the function in our interface
+ * module.
+ *
+ * Loop ported from libjansson utf.c:utf8_check_string()
+ */
+ for (pos = 0; pos < len; pos += count) {
+ count = json_utf8_check_first(str[pos]);
+ if (count == 0) {
+ res = 0;
+ break;
+ } else if (count > 1) {
+ if (count > len - pos) {
+ /* UTF-8 needs more than we have left in the string. */
+ res = 0;
+ break;
+ }
+
+ if (!json_utf8_check_full(&str[pos], count)) {
+ res = 0;
+ break;
+ }
+ }
+ }
+
+ if (!res) {
+ ast_debug(1, "String '%.*s' is not UTF-8 for json conversion\n", (int) len, str);
+ }
+ return res;
+}
+
+int ast_json_utf8_check(const char *str)
+{
+ return str ? ast_json_utf8_check_len(str, strlen(str)) : 0;
+}
struct ast_json *ast_json_true(void)
{
@@ -721,16 +842,16 @@ struct ast_json *ast_json_deep_copy(const struct ast_json *value)
struct ast_json *ast_json_name_number(const char *name, const char *number)
{
return ast_json_pack("{s: s, s: s}",
- "name", name,
- "number", number);
+ "name", AST_JSON_UTF8_VALIDATE(name),
+ "number", AST_JSON_UTF8_VALIDATE(number));
}
struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority)
{
return ast_json_pack("{s: o, s: o, s: o}",
- "context", context ? ast_json_string_create(context) : ast_json_null(),
- "exten", exten ? ast_json_string_create(exten) : ast_json_null(),
- "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null());
+ "context", context ? ast_json_string_create(context) : ast_json_null(),
+ "exten", exten ? ast_json_string_create(exten) : ast_json_null(),
+ "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null());
}
struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone)
@@ -821,7 +942,7 @@ static struct ast_json *json_party_number(struct ast_party_number *number)
return NULL;
}
return ast_json_pack("{s: s, s: i, s: i, s: s}",
- "number", number->str,
+ "number", AST_JSON_UTF8_VALIDATE(number->str),
"plan", number->plan,
"presentation", number->presentation,
"presentation_txt", ast_describe_caller_presentation(number->presentation));
@@ -833,7 +954,7 @@ static struct ast_json *json_party_name(struct ast_party_name *name)
return NULL;
}
return ast_json_pack("{s: s, s: s, s: i, s: s}",
- "name", name->str,
+ "name", AST_JSON_UTF8_VALIDATE(name->str),
"character_set", ast_party_name_charset_describe(name->char_set),
"presentation", name->presentation,
"presentation_txt", ast_describe_caller_presentation(name->presentation));
@@ -845,7 +966,7 @@ static struct ast_json *json_party_subaddress(struct ast_party_subaddress *subad
return NULL;
}
return ast_json_pack("{s: s, s: i, s: b}",
- "subaddress", subaddress->str,
+ "subaddress", AST_JSON_UTF8_VALIDATE(subaddress->str),
"type", subaddress->type,
"odd", subaddress->odd_even_indicator);
}
@@ -865,17 +986,20 @@ struct ast_json *ast_json_party_id(struct ast_party_id *party)
}
/* Party number */
- if (party->number.valid && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) {
+ if (party->number.valid
+ && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) {
return NULL;
}
/* Party name */
- if (party->name.valid && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) {
+ if (party->name.valid
+ && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) {
return NULL;
}
/* Party subaddress */
- if (party->subaddress.valid && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) {
+ if (party->subaddress.valid
+ && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) {
return NULL;
}
diff --git a/res/res_fax.c b/res/res_fax.c
index ab0945a89..666c2d997 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -1415,11 +1415,13 @@ static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_de
}
json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: o}",
- "type", "status",
- "operation", (details->caps & AST_FAX_TECH_GATEWAY) ? "gateway" : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
- "status", status,
- "local_station_id", details->localstationid,
- "filenames", json_filenames);
+ "type", "status",
+ "operation", (details->caps & AST_FAX_TECH_GATEWAY)
+ ? "gateway"
+ : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
+ "status", status,
+ "local_station_id", AST_JSON_UTF8_VALIDATE(details->localstationid),
+ "filenames", json_filenames);
if (!json_object) {
return -1;
}
diff --git a/res/stasis/app.c b/res/stasis/app.c
index 4e18aa5ae..957ed7f69 100644
--- a/res/stasis/app.c
+++ b/res/stasis/app.c
@@ -456,7 +456,7 @@ static struct ast_json *channel_dialplan(
"type", "ChannelDialplan",
"timestamp", ast_json_timeval(*tv, NULL),
"dialplan_app", new_snapshot->appl,
- "dialplan_app_data", new_snapshot->data,
+ "dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->data),
"channel", json_channel);
}
diff --git a/tests/test_json.c b/tests/test_json.c
index 9d624cdc6..206bd8a39 100644
--- a/tests/test_json.c
+++ b/tests/test_json.c
@@ -1597,11 +1597,26 @@ AST_TEST_DEFINE(json_test_clever_circle)
return AST_TEST_PASS;
}
-AST_TEST_DEFINE(json_test_name_number)
+static int test_name_number(const char *name, const char *number)
{
- RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
- RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
+ int res;
+ struct ast_json *uut;
+ struct ast_json *expected;
+
+ expected = ast_json_pack("{s: s, s: s}",
+ "name", name ?: "",
+ "number", number ?: "");
+ uut = ast_json_name_number(name, number);
+
+ res = ast_json_equal(expected, uut);
+ ast_json_unref(expected);
+ ast_json_unref(uut);
+ return res;
+}
+
+AST_TEST_DEFINE(json_test_name_number)
+{
switch (cmd) {
case TEST_INIT:
info->name = "name_number";
@@ -1613,15 +1628,10 @@ AST_TEST_DEFINE(json_test_name_number)
break;
}
- ast_test_validate(test, NULL == ast_json_name_number("name", NULL));
- ast_test_validate(test, NULL == ast_json_name_number(NULL, "1234"));
- ast_test_validate(test, NULL == ast_json_name_number(NULL, NULL));
-
- expected = ast_json_pack("{s: s, s: s}",
- "name", "Jenny",
- "number", "867-5309");
- uut = ast_json_name_number("Jenny", "867-5309");
- ast_test_validate(test, ast_json_equal(expected, uut));
+ ast_test_validate(test, test_name_number("name", NULL));
+ ast_test_validate(test, test_name_number(NULL, "1234"));
+ ast_test_validate(test, test_name_number(NULL, NULL));
+ ast_test_validate(test, test_name_number("Jenny", "867-5309"));
return AST_TEST_PASS;
}