From 68718cc06afb4d6032041b70895983ab78c56216 Mon Sep 17 00:00:00 2001 From: Justin Seyster Date: Thu, 7 Apr 2011 20:14:38 -0400 Subject: [PATCH] Clarifies rules for allowed symbol and param names. Simplifies tc_declare_call_symbol parsing code. --- src/tracecut.c | 297 ++++++++++++++++++++++++++++--------------------- src/tracecut.h | 22 ++-- 2 files changed, 186 insertions(+), 133 deletions(-) diff --git a/src/tracecut.c b/src/tracecut.c index bcb526c..8205a2f 100644 --- a/src/tracecut.c +++ b/src/tracecut.c @@ -31,6 +31,7 @@ #undef PACKAGE_TARNAME #undef PACKAGE_VERSION +#include #include #include #include @@ -169,6 +170,33 @@ return_error (struct tc_tracecut *tc, enum tc_error tc_error) return tc_error; } +/* Tracecut identifiers must consist entirely of the characters + [_0-9a-zA-Z] with no spaces. */ +static int +is_id_char(char c) +{ + return (c == '_' || ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')) + || ((c >= 'A') && (c <= 'Z'))); +} + +/* Does the input string follow the rules for tracecut identifiers? */ +static int +is_valid_identifier(const char *str) +{ + int i; + + for (i = 0; str[i] != '\0'; i++) + { + if (!is_id_char (*str)) + return 0; + } + + if (i > TC_MAX_ID_SIZE) + return 0; + + return 1; +} + /** * The first operation on a tracecut that fails stores its error code * in the tracecut. This function returns that error code, or @@ -201,8 +229,8 @@ tc_reset_error (struct tc_tracecut *tc) tc->tc_error = TC_SUCCESS; } -enum tc_error -tc_check_param_type(const struct aop_type *type) +static enum tc_error +check_param_type(const struct aop_type *type) { if(aop_is_pointer_type (type) || aop_is_all_signed_subtype (type) || @@ -232,6 +260,10 @@ tc_check_param_type(const struct aop_type *type) * started; * - #TC_DUPLICATE, if there already exists a param with the * specified name; + * - #TC_BAD_ID if name is not an acceptable identifier. (Identifiers + * must only contain letters, numbers and the underscore character, + * with no spaces. Identifiers are case sensitive and should be no + * longer than #TC_MAX_ID_SIZE.) * - #TC_INVAL, if aop_is_pointer_type() is false for the specified * type; * - #TC_NOMEM, if memory runs out. @@ -246,9 +278,12 @@ tc_add_param (struct tc_tracecut *tc, const char *name, if (tc_in_compilation) return return_error (tc, TC_BAD_CONTEXT); - tc_err = tc_check_param_type(type); + if (!is_valid_identifier (name)) + return return_error (tc, TC_BAD_ID); + + tc_err = check_param_type(type); if(tc_err != TC_SUCCESS) - return tc_err; + return return_error (tc, tc_err); if (lookup_param (tc, name) != NULL) return return_error (tc, TC_DUPLICATE); @@ -310,6 +345,10 @@ lookup_call_symbol (struct tc_tracecut *tc, const char *name) * started; * - #TC_DUPLICATE, if there already exists a symbol with the * specified name; + * - #TC_BAD_ID if name is not an acceptable identifier. (Identifiers + * must only contain letters, numbers and the underscore character, + * with no spaces. Identifiers are case sensitive and should be no + * longer than #TC_MAX_ID_SIZE.) * - #TC_NOMEM, if memory runs out. */ enum tc_error @@ -321,6 +360,9 @@ tc_add_call_symbol (struct tc_tracecut *tc, const char *name, if (tc_in_compilation) return return_error (tc, TC_BAD_CONTEXT); + if (!is_valid_identifier (name)) + return return_error (tc, TC_BAD_ID); + if (lookup_call_symbol (tc, name) != NULL) return return_error (tc, TC_DUPLICATE); @@ -432,6 +474,14 @@ tc_bind_to_return_value (struct tc_tracecut *tc, const char *param_name, return add_call_symbol_binding (tc, param_name, symbol_name, -1); } +/** + * \cond HIDDEN_SYMBOLS + */ +#define MAX_FUNC_SIZE 255 +/** + * \endcond + */ + /** * Create a function call symbol along with its bindings in one * statement. The declaration is a string containing the function @@ -460,11 +510,15 @@ tc_bind_to_return_value (struct tc_tracecut *tc, const char *param_name, * - #TC_BAD_CONTEXT, when called after compilation has already * started; * - #TC_INVAL, when the declaration is invalid because of syntax - errors; + * errors; * - #TC_DUPLICATE, if there already exists a symbol with the * specified name; + * - #TC_BAD_ID if name is not an acceptable identifier. (Identifiers + * must only contain letters, numbers and the underscore character, + * with no spaces. Identifiers are case sensitive and should be no + * longer than #TC_MAX_ID_SIZE.) * - #TC_NOENT, if one of the parameters in the declaration does not - exist; + * exist; * - #TC_NOMEM, if memory runs out. */ enum tc_error @@ -472,54 +526,57 @@ tc_declare_call_symbol (struct tc_tracecut *tc, const char *name, const char *declaration, enum aop_insert_location location) { - int i = 0, pos = 0; - int param_num = 0, space_track = 0; + int i = 0, pos; + int param_num; enum tc_error tc_err; - char func_name[MAX_FUNC_SIZE], return_param[MAX_PARAM_SIZE], param_name[MAX_PARAM_SIZE]; + char func_name[MAX_FUNC_SIZE]; + char param_name[TC_MAX_ID_SIZE]; if (tc_in_compilation) return return_error (tc, TC_BAD_CONTEXT); - - strcpy(return_param, ""); - strcpy(func_name, ""); - strcpy(param_name, ""); + + strcpy (param_name, ""); /* Eliminate white spaces */ - while (declaration[i] == ' ') + while (isspace(declaration[i])) i++; /* Check if return parameter is present */ if (declaration[i] == '(') { - /* Copy the return param */ + /* Consume the (. */ i++; + /* Remove beginning spaces */ - while (declaration[i] == ' ') + while (isspace(declaration[i])) i++; - while (declaration[i] != ')') + + if (declaration[i] == '?') { - /* If space, copy the name */ - if(declaration[i] == ' ') - break; - return_param[pos++] = declaration[i++]; - } - return_param[pos] = '\0'; - pos = 0; - if (declaration[i] == ')') + /* Consume the ?. */ i++; + } else { - while (declaration[i] != ')') - { - if(declaration[i] == ' ') - i++; - else - { - return TC_INVAL; - } - } - i++; + /* Copy the return param */ + pos = 0; + while (is_id_char(declaration[i]) && pos + 1 < TC_MAX_ID_SIZE) + param_name[pos++] = declaration[i++]; + param_name[pos] = '\0'; + + /* Bad return param. */ + if (pos == 0) + return return_error (tc, TC_INVAL); } + + while (isspace(declaration[i])) + i++; + + /* Unmatched parenthesis. */ + if (declaration[i] != ')') + return return_error (tc, TC_INVAL); + + i++; /* Consume the ). */ } /* Ignore the white spaces in between */ @@ -527,113 +584,99 @@ tc_declare_call_symbol (struct tc_tracecut *tc, const char *name, i++; /* Copy the function name */ - while(declaration[i] != '(') - { - if (declaration[i] == ' ') - break; - func_name[pos++] = declaration[i++]; - } - - func_name[pos] = '\0'; pos = 0; + while(is_id_char(declaration[i]) && pos + 1 < MAX_FUNC_SIZE) + func_name[pos++] = declaration[i++]; + func_name[pos] = '\0'; - if (declaration[i] == '(') + while (isspace(declaration[i])) i++; - else - { - while (declaration[i] != '(') - { - if (declaration[i] == ' ') - i++; - else - { - return TC_INVAL; - } - } - i++; - } - + + if (pos == 0 || declaration[i] != '(') + return return_error (tc, TC_INVAL); + + /* Consume the (. */ + i++; + /* Add functiona name */ - if (strcmp(func_name, "")) - { - tc_err = tc_add_call_symbol (tc, - name, - func_name, - location); - if (tc_err != TC_SUCCESS) - { - return tc_err; - } - } + tc_err = tc_add_call_symbol (tc, name, func_name, location); + if (tc_err != TC_SUCCESS) + return tc_err; /* Bind return parameter */ - if (strcmp(return_param, "")) + if (strcmp(param_name, "") != 0) { - tc_err = tc_bind_to_return_value (tc, - return_param, - name); - - if (tc_err != TC_SUCCESS) - { - return tc_err; - } - } + tc_err = tc_bind_to_return_value (tc, param_name, name); - /* Skip spaces */ - while (declaration[i] == ' ') - i++; + if (tc_err != TC_SUCCESS) + return tc_err; + } - /* Parse function parameters and add them */ - while (declaration[i] != '\0') + /* Parse function parameters and add them. */ + for (param_num = 0; ; param_num++) { - if (declaration[i] == ' ' && pos == 0) - { - /* If it is beginning of the parameter */ + /* Skip spaces */ + while (isspace(declaration[i])) + i++; + + /* Special case: no paremeters. */ + if (declaration[i] == ')') + { i++; - continue; - } - else if (declaration[i] == ' ' && pos != 0) + break; + } + + if (declaration[i] == '?') { - /* Space while parsing the param name */ - space_track = 1; + /* Consume the ? and ignore this parameter. */ i++; - continue; } - else if ((declaration[i] != ')' && declaration[i] != ',') && - (space_track == 1)) + else { - return TC_INVAL; + pos = 0; + while (is_id_char(declaration[i]) && pos + 1 < TC_MAX_ID_SIZE) + param_name[pos++] = declaration[i++]; + param_name[pos] = '\0'; + + if (pos == 0) + return return_error (tc, TC_INVAL); + + /* Param found, insert it */ + tc_err = tc_bind_to_call_param (tc, param_name, name, param_num); + + if (tc_err != TC_SUCCESS) + return tc_err; + } + + /* Skip spaces */ + while (isspace(declaration[i])) + i++; + + if (declaration[i] == ')') + { + /* Done with parameters. */ + i++; + break; + } + else if (declaration[i] == ',') + { + /* Consume the comma. */ + i++; + } + else + { + return return_error (tc, TC_INVAL); } - else if (declaration[i] == ',' || declaration[i] == ')') - { - /* Store param */ - space_track = 0; - param_name[pos] = '\0'; - - printf("%s\n", param_name); - if(strcmp(param_name, "?") && pos != 0) - { - /* Param found, insert it */ - tc_err = tc_bind_to_call_param (tc, - param_name, - name, - param_num); - - if (tc_err != TC_SUCCESS) - { - return tc_err; - } - } - param_num++; - i++; - pos = 0; - continue; - } - - param_name[pos++] = declaration[i++]; } - return return_error (tc, TC_SUCCESS); + /* Make sure there's no junk hanging off the end of the + declaration. */ + while (isspace(declaration[i])) + i++; + if (declaration[i] != '\0') + return return_error (tc, TC_INVAL); + + return return_error (tc, TC_SUCCESS); } /** @@ -903,10 +946,16 @@ insert_transition_event_advice (struct aop_joinpoint *jp, int tc_index, AOP_TERM_ARG); } +/** + * \cond HIDDEN_SYMBOLS + */ struct join_on_call_arg { struct tc_tracecut *tc; struct tc_call_symbol *symbol; }; +/** + * \endcond + */ static void join_on_call (struct aop_joinpoint *jp, void *callback_arg) diff --git a/src/tracecut.h b/src/tracecut.h index 6149dc4..3ae3768 100644 --- a/src/tracecut.h +++ b/src/tracecut.h @@ -40,14 +40,15 @@ * All tracecut functions have a tc_ prefix. */ -#define MAX_PARAM_IN_DECL 10 -#define MAX_PARAM_SIZE 100 -#define MAX_FUNC_SIZE 100 - struct aop_joinpoint; struct aop_type; struct tc_tracecut; +/** + * Maximum size for a symbol and param names. + */ +#define TC_MAX_ID_SIZE 255 + /** * Possible error return values for tracecut functions. */ @@ -73,6 +74,14 @@ enum tc_error { */ TC_DUPLICATE, + /** + * Attempt to name a symbol of param with a bad identifier. + * (Identifiers must only contain letters, numbers and the + * underscore character, with no spaces. Identifiers are case + * sensitive.) + */ + TC_BAD_ID, + /** * Attempt to reference a name that does not exist. */ @@ -84,11 +93,6 @@ enum tc_error { TC_NOMEM, }; -struct param_name_t -{ - char param_name[MAX_PARAM_SIZE]; -}; - extern enum tc_error tc_error_code (struct tc_tracecut *tc); extern void tc_reset_error (struct tc_tracecut *tc); -- 2.34.1