From 654c1444b546fd79b209288b93ed4e87d9bb8a2b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 23 Jan 2015 16:24:52 -0500 Subject: [PATCH] Add utility function to validate CTF identifiers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Introduces bt_ctf_validate_identifier() which validates a given identifier against the list of CTF reserved keywords. This function may evolve to perform additional validity checks in the future as the CTF specification moves forward. Acked-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/Makefile.am | 3 +- formats/ctf/ir/clock.c | 3 +- formats/ctf/ir/event-types.c | 9 +- formats/ctf/ir/event.c | 7 +- formats/ctf/ir/stream-class.c | 3 +- formats/ctf/ir/trace.c | 79 +-------------- formats/ctf/ir/utils.c | 106 +++++++++++++++++++++ include/Makefile.am | 3 +- include/babeltrace/ctf-ir/trace-internal.h | 4 - include/babeltrace/ctf-ir/utils.h | 56 +++++++++++ 10 files changed, 181 insertions(+), 92 deletions(-) create mode 100644 formats/ctf/ir/utils.c create mode 100644 include/babeltrace/ctf-ir/utils.h diff --git a/formats/ctf/ir/Makefile.am b/formats/ctf/ir/Makefile.am index 955efc74..b3609176 100644 --- a/formats/ctf/ir/Makefile.am +++ b/formats/ctf/ir/Makefile.am @@ -9,7 +9,8 @@ libctf_ir_la_SOURCES = \ event-types.c \ stream.c \ stream-class.c \ - trace.c + trace.c \ + utils.c libctf_ir_la_LIBADD = \ $(top_builddir)/lib/libbabeltrace.la diff --git a/formats/ctf/ir/clock.c b/formats/ctf/ir/clock.c index fa073073..d1f435d5 100644 --- a/formats/ctf/ir/clock.c +++ b/formats/ctf/ir/clock.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include @@ -57,7 +58,7 @@ int bt_ctf_clock_set_name(struct bt_ctf_clock *clock, { int ret = 0; - if (validate_identifier(name)) { + if (bt_ctf_validate_identifier(name)) { ret = -1; goto end; } diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 1d5f0909..a57aaf5a 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -1032,7 +1033,7 @@ int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type, struct bt_ctf_field_type_structure *structure; if (!type || !field_type || type->frozen || - validate_identifier(field_name) || + bt_ctf_validate_identifier(field_name) || (type->declaration->id != CTF_TYPE_STRUCT) || bt_ctf_field_type_validate(field_type)) { ret = -1; @@ -1140,7 +1141,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_create( { struct bt_ctf_field_type_variant *variant = NULL; - if (!enum_tag || validate_identifier(tag_name) || + if (!enum_tag || bt_ctf_validate_identifier(tag_name) || (enum_tag->declaration->id != CTF_TYPE_ENUM)) { goto error; } @@ -1209,7 +1210,7 @@ int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type, GQuark field_name_quark = g_quark_from_string(field_name); if (!type || !field_type || type->frozen || - validate_identifier(field_name) || + bt_ctf_validate_identifier(field_name) || (type->declaration->id != CTF_TYPE_VARIANT) || bt_ctf_field_type_validate(field_type)) { ret = -1; @@ -1407,7 +1408,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_sequence_create( { struct bt_ctf_field_type_sequence *sequence = NULL; - if (!element_type || validate_identifier(length_field_name) || + if (!element_type || bt_ctf_validate_identifier(length_field_name) || bt_ctf_field_type_validate(element_type)) { goto error; } diff --git a/formats/ctf/ir/event.c b/formats/ctf/ir/event.c index 943295cb..000f5f7c 100644 --- a/formats/ctf/ir/event.c +++ b/formats/ctf/ir/event.c @@ -34,6 +34,7 @@ #include #include #include +#include #include static @@ -45,7 +46,7 @@ struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name) { struct bt_ctf_event_class *event_class = NULL; - if (validate_identifier(name)) { + if (bt_ctf_validate_identifier(name)) { goto end; } @@ -133,7 +134,7 @@ int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class, { int ret = 0; - if (!event_class || !type || validate_identifier(name) || + if (!event_class || !type || bt_ctf_validate_identifier(name) || event_class->frozen) { ret = -1; goto end; @@ -346,7 +347,7 @@ int bt_ctf_event_set_payload(struct bt_ctf_event *event, { int ret = 0; - if (!event || !value || validate_identifier(name)) { + if (!event || !value || bt_ctf_validate_identifier(name)) { ret = -1; goto end; } diff --git a/formats/ctf/ir/stream-class.c b/formats/ctf/ir/stream-class.c index 058f4b29..d034340d 100644 --- a/formats/ctf/ir/stream-class.c +++ b/formats/ctf/ir/stream-class.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name) int ret; struct bt_ctf_stream_class *stream_class = NULL; - if (!name || !strlen(name)) { + if (!name || !strlen(name) || bt_ctf_validate_identifier(name)) { goto error; } diff --git a/formats/ctf/ir/trace.c b/formats/ctf/ir/trace.c index 6ffef05b..68bfd67a 100644 --- a/formats/ctf/ir/trace.c +++ b/formats/ctf/ir/trace.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define DEFAULT_IDENTIFIER_SIZE 128 @@ -44,13 +45,6 @@ void bt_ctf_trace_destroy(struct bt_ctf_ref *ref); static int init_trace_packet_header(struct bt_ctf_trace *trace); -static -const char * const reserved_keywords_str[] = {"align", "callsite", - "const", "char", "clock", "double", "enum", "env", "event", - "floating_point", "float", "integer", "int", "long", "short", "signed", - "stream", "string", "struct", "trace", "typealias", "typedef", - "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"}; - static const unsigned int field_type_aliases_alignments[] = { [FIELD_TYPE_ALIAS_UINT5_T] = 1, @@ -69,10 +63,6 @@ const unsigned int field_type_aliases_sizes[] = { [FIELD_TYPE_ALIAS_UINT64_T] = 64, }; -static GHashTable *reserved_keywords_set; -static int init_done; -static int global_data_refcount; - struct bt_ctf_trace *bt_ctf_trace_create(void) { struct bt_ctf_trace *trace = NULL; @@ -211,7 +201,7 @@ int bt_ctf_trace_add_environment_field(struct bt_ctf_trace *trace, char *escaped_value = NULL; int ret = 0; - if (!trace || !name || !value || validate_identifier(name)) { + if (!trace || !name || !value || bt_ctf_validate_identifier(name)) { ret = -1; goto error; } @@ -523,40 +513,6 @@ void bt_ctf_trace_put(struct bt_ctf_trace *trace) bt_ctf_ref_put(&trace->ref_count, bt_ctf_trace_destroy); } -BT_HIDDEN -int validate_identifier(const char *input_string) -{ - int ret = 0; - char *string = NULL; - char *save_ptr, *token; - - if (!input_string || input_string[0] == '\0') { - ret = -1; - goto end; - } - - string = strdup(input_string); - if (!string) { - ret = -1; - goto end; - } - - token = strtok_r(string, " ", &save_ptr); - while (token) { - if (g_hash_table_lookup_extended(reserved_keywords_set, - GINT_TO_POINTER(g_quark_from_string(token)), - NULL, NULL)) { - ret = -1; - goto end; - } - - token = strtok_r(NULL, " ", &save_ptr); - } -end: - free(string); - return ret; -} - BT_HIDDEN struct bt_ctf_field_type *get_field_type(enum field_type_alias alias) { @@ -641,34 +597,3 @@ void environment_variable_destroy(struct environment_variable *var) g_string_free(var->value, TRUE); g_free(var); } - -static __attribute__((constructor)) -void trace_init(void) -{ - size_t i; - const size_t reserved_keywords_count = - sizeof(reserved_keywords_str) / sizeof(char *); - - global_data_refcount++; - if (init_done) { - return; - } - - reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal); - for (i = 0; i < reserved_keywords_count; i++) { - gpointer quark = GINT_TO_POINTER(g_quark_from_string( - reserved_keywords_str[i])); - - g_hash_table_insert(reserved_keywords_set, quark, quark); - } - - init_done = 1; -} - -static __attribute__((destructor)) -void trace_finalize(void) -{ - if (--global_data_refcount == 0) { - g_hash_table_destroy(reserved_keywords_set); - } -} diff --git a/formats/ctf/ir/utils.c b/formats/ctf/ir/utils.c new file mode 100644 index 00000000..318b12da --- /dev/null +++ b/formats/ctf/ir/utils.c @@ -0,0 +1,106 @@ +/* + * utils.c + * + * Babeltrace CTF IR - Utilities + * + * Copyright 2015 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +static +const char * const reserved_keywords_str[] = {"align", "callsite", + "const", "char", "clock", "double", "enum", "env", "event", + "floating_point", "float", "integer", "int", "long", "short", "signed", + "stream", "string", "struct", "trace", "typealias", "typedef", + "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"}; + +static GHashTable *reserved_keywords_set; +static int init_done; +static int global_data_refcount; + +static __attribute__((constructor)) +void trace_init(void) +{ + size_t i; + const size_t reserved_keywords_count = + sizeof(reserved_keywords_str) / sizeof(char *); + + global_data_refcount++; + if (init_done) { + return; + } + + reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal); + for (i = 0; i < reserved_keywords_count; i++) { + gpointer quark = GINT_TO_POINTER(g_quark_from_string( + reserved_keywords_str[i])); + + g_hash_table_insert(reserved_keywords_set, quark, quark); + } + + init_done = 1; +} + +static __attribute__((destructor)) +void trace_finalize(void) +{ + if (--global_data_refcount == 0) { + g_hash_table_destroy(reserved_keywords_set); + } +} + +int bt_ctf_validate_identifier(const char *input_string) +{ + int ret = 0; + char *string = NULL; + char *save_ptr, *token; + + if (!input_string || input_string[0] == '\0') { + ret = -1; + goto end; + } + + string = strdup(input_string); + if (!string) { + ret = -1; + goto end; + } + + token = strtok_r(string, " ", &save_ptr); + while (token) { + if (g_hash_table_lookup_extended(reserved_keywords_set, + GINT_TO_POINTER(g_quark_from_string(token)), + NULL, NULL)) { + ret = -1; + goto end; + } + + token = strtok_r(NULL, " ", &save_ptr); + } +end: + free(string); + return ret; +} diff --git a/include/Makefile.am b/include/Makefile.am index 3f7f0987..9f106c96 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -28,7 +28,8 @@ babeltracectfirinclude_HEADERS = \ babeltrace/ctf-ir/event.h \ babeltrace/ctf-ir/stream.h \ babeltrace/ctf-ir/stream-class.h \ - babeltrace/ctf-ir/trace.h + babeltrace/ctf-ir/trace.h \ + babeltrace/ctf-ir/utils.h noinst_HEADERS = \ babeltrace/align.h \ diff --git a/include/babeltrace/ctf-ir/trace-internal.h b/include/babeltrace/ctf-ir/trace-internal.h index dc0b7069..125b554b 100644 --- a/include/babeltrace/ctf-ir/trace-internal.h +++ b/include/babeltrace/ctf-ir/trace-internal.h @@ -69,10 +69,6 @@ struct metadata_context { unsigned int current_indentation_level; }; -/* Checks that the string does not contain a reserved keyword */ -BT_HIDDEN -int validate_identifier(const char *string); - BT_HIDDEN const char *get_byte_order_string(int byte_order); diff --git a/include/babeltrace/ctf-ir/utils.h b/include/babeltrace/ctf-ir/utils.h new file mode 100644 index 00000000..d661ed88 --- /dev/null +++ b/include/babeltrace/ctf-ir/utils.h @@ -0,0 +1,56 @@ +#ifndef BABELTRACE_CTF_IR_UTILS_H +#define BABELTRACE_CTF_IR_UTILS_H + +/* + * BabelTrace - CTF IR: Utilities + * + * Copyright 2015 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * bt_ctf_validate_identifier: validate an identifier against the CTF spec. + * + * Validate that an identifier meets the CTF specification's restrictions on + * identifiers. An identifier will be rejected if it is a keyword defined + * in the CTF specification or if it does not meet any other requirement imposed + * on identifiers. + * + * Note that this will not check whether or not the identifier clashes with + * identifiers used in a given trace. + * + * Returns 0 if the identifier is valid, a negative value on error. + */ +extern int bt_ctf_validate_identifier(const char *identifier); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_CTF_IR_UTILS_H */ -- 2.34.1