diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-08-20 13:57:05 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-08-20 13:57:05 -0400 |
commit | edf5a327c5a27db218b4240b758669f5572e9565 (patch) | |
tree | c7a1f09943439f74b22dfc2e6761ba8a6dcbaafe /src/lib/confmgt | |
parent | 4b1e0dd5b53528996a3a0f92717e5ccbb8819a4b (diff) | |
parent | e8790971f6120cc3e4fd2acd41f5dd0512f52068 (diff) | |
download | tor-edf5a327c5a27db218b4240b758669f5572e9565.tar.gz tor-edf5a327c5a27db218b4240b758669f5572e9565.zip |
Merge branch 'ticket30914' into ticket30914_merged
Diffstat (limited to 'src/lib/confmgt')
-rw-r--r-- | src/lib/confmgt/include.am | 2 | ||||
-rw-r--r-- | src/lib/confmgt/structvar.c | 226 | ||||
-rw-r--r-- | src/lib/confmgt/structvar.h | 54 | ||||
-rw-r--r-- | src/lib/confmgt/typedvar.c | 18 |
4 files changed, 292 insertions, 8 deletions
diff --git a/src/lib/confmgt/include.am b/src/lib/confmgt/include.am index a2c7649957..aa5b37fdb5 100644 --- a/src/lib/confmgt/include.am +++ b/src/lib/confmgt/include.am @@ -6,6 +6,7 @@ endif # ADD_C_FILE: INSERT SOURCES HERE. src_lib_libtor_confmgt_a_SOURCES = \ + src/lib/confmgt/structvar.c \ src/lib/confmgt/type_defs.c \ src/lib/confmgt/typedvar.c \ src/lib/confmgt/unitparse.c @@ -17,6 +18,7 @@ src_lib_libtor_confmgt_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ + src/lib/confmgt/structvar.h \ src/lib/confmgt/type_defs.h \ src/lib/confmgt/typedvar.h \ src/lib/confmgt/unitparse.h \ diff --git a/src/lib/confmgt/structvar.c b/src/lib/confmgt/structvar.c new file mode 100644 index 0000000000..38f8e5dd7a --- /dev/null +++ b/src/lib/confmgt/structvar.c @@ -0,0 +1,226 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file structvar.c + * @brief Functions to manipulate named and typed elements of + * a structure. + * + * These functions represent a low-level API for accessing a member of a + * structure. They use typedvar.c to work, and they are used in turn by the + * configuration system to examine and set fields in configuration objects + * used by individual modules. + * + * Almost no code should call these directly. + **/ + +#include "orconfig.h" +#include "lib/confmgt/structvar.h" +#include "lib/cc/compat_compiler.h" +#include "lib/conf/conftypes.h" +#include "lib/confmgt/type_defs.h" +#include "lib/confmgt/typedvar.h" +#include "lib/log/util_bug.h" + +#include "lib/confmgt/var_type_def_st.h" + +#include <stddef.h> + +/** + * Set the 'magic number' on <b>object</b> to correspond to decl. + **/ +void +struct_set_magic(void *object, const struct_magic_decl_t *decl) +{ + tor_assert(object); + tor_assert(decl); + uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset); + *ptr = decl->magic_val; +} + +/** + * Assert that the 'magic number' on <b>object</b> to corresponds to decl. + **/ +void +struct_check_magic(const void *object, const struct_magic_decl_t *decl) +{ + tor_assert(object); + tor_assert(decl); + + const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset); + tor_assertf(*ptr == decl->magic_val, + "Bad magic number on purported %s object. " + "Expected %"PRIu32"x but got "PRIu32"x.", + decl->magic_val, *ptr); +} + +/** + * Return a mutable pointer to the member of <b>object</b> described + * by <b>member</b>. + **/ +void * +struct_get_mptr(void *object, const struct_member_t *member) +{ + tor_assert(object); + return STRUCT_VAR_P(object, member->offset); +} + +/** + * Return a const pointer to the member of <b>object</b> described + * by <b>member</b>. + **/ +const void * +struct_get_ptr(const void *object, const struct_member_t *member) +{ + tor_assert(object); + return STRUCT_VAR_P(object, member->offset); +} + +/** + * Helper: given a struct_member_t, look up the type definition for its + * variable. + */ +static const var_type_def_t * +get_type_def(const struct_member_t *member) +{ + if (member->type_def) + return member->type_def; + + return lookup_type_def(member->type); +} + +/** + * (As typed_var_assign, but assign a value to the member of <b>object</b> + * defined by <b>member</b>.) + **/ +int +struct_var_assign(void *object, const char *value, char **errmsg, + const struct_member_t *member) +{ + void *p = struct_get_mptr(object, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_assign_ex(p, value, errmsg, def); +} + +/** + * (As typed_var_free, but free and clear the member of <b>object</b> defined + * by <b>member</b>.) + **/ +void +struct_var_free(void *object, const struct_member_t *member) +{ + void *p = struct_get_mptr(object, member); + const var_type_def_t *def = get_type_def(member); + + typed_var_free_ex(p, def); +} + +/** + * (As typed_var_encode, but encode the member of <b>object</b> defined + * by <b>member</b>.) + **/ +char * +struct_var_encode(const void *object, const struct_member_t *member) +{ + const void *p = struct_get_ptr(object, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_encode_ex(p, def); +} + +/** + * (As typed_var_copy, but copy from <b>src</b> to <b>dest</b> the member + * defined by <b>member</b>.) + **/ +int +struct_var_copy(void *dest, const void *src, const struct_member_t *member) +{ + void *p_dest = struct_get_mptr(dest, member); + const void *p_src = struct_get_ptr(src, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_copy_ex(p_dest, p_src, def); +} + +/** + * (As typed_var_eq, but compare the members of <b>a</b> and <b>b</b> + * defined by <b>member</b>.) + **/ +bool +struct_var_eq(const void *a, const void *b, const struct_member_t *member) +{ + const void *p_a = struct_get_ptr(a, member); + const void *p_b = struct_get_ptr(b, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_eq_ex(p_a, p_b, def); +} + +/** + * (As typed_var_ok, but validate the member of <b>object</b> defined by + * <b>member</b>.) + **/ +bool +struct_var_ok(const void *object, const struct_member_t *member) +{ + const void *p = struct_get_ptr(object, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_ok_ex(p, def); +} + +/** + * (As typed_var_kvassign, but assign a value to the member of <b>object</b> + * defined by <b>member</b>.) + **/ +int +struct_var_kvassign(void *object, const struct config_line_t *line, + char **errmsg, + const struct_member_t *member) +{ + void *p = struct_get_mptr(object, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_kvassign_ex(p, line, errmsg, def); +} + +/** + * (As typed_var_kvencode, but encode the value of the member of <b>object</b> + * defined by <b>member</b>.) + **/ +struct config_line_t * +struct_var_kvencode(const void *object, const struct_member_t *member) +{ + const void *p = struct_get_ptr(object, member); + const var_type_def_t *def = get_type_def(member); + + return typed_var_kvencode_ex(member->name, p, def); +} + +/** + * Return the official name of this struct member. + **/ +const char * +struct_var_get_name(const struct_member_t *member) +{ + return member->name; +} + +/** + * Return the type name for this struct member. + * + * Do not use the output of this function to inspect a type within Tor. It is + * suitable for debugging, informing the controller or user of a variable's + * type, etc. + **/ +const char * +struct_var_get_typename(const struct_member_t *member) +{ + const var_type_def_t *def = get_type_def(member); + + return def ? def->name : NULL; +} diff --git a/src/lib/confmgt/structvar.h b/src/lib/confmgt/structvar.h new file mode 100644 index 0000000000..92b9b6fc71 --- /dev/null +++ b/src/lib/confmgt/structvar.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file structvar.h + * @brief Header for lib/confmgt/structvar.c + **/ + +#ifndef TOR_LIB_CONFMGT_STRUCTVAR_H +#define TOR_LIB_CONFMGT_STRUCTVAR_H + +struct struct_magic_decl_t; +struct struct_member_t; +struct config_line_t; + +#include <stdbool.h> + +void struct_set_magic(void *object, + const struct struct_magic_decl_t *decl); +void struct_check_magic(const void *object, + const struct struct_magic_decl_t *decl); + +void *struct_get_mptr(void *object, + const struct struct_member_t *member); +const void *struct_get_ptr(const void *object, + const struct struct_member_t *member); + +int struct_var_assign(void *object, const char *value, char **errmsg, + const struct struct_member_t *member); +void struct_var_free(void *object, + const struct struct_member_t *member); +char *struct_var_encode(const void *object, + const struct struct_member_t *member); +int struct_var_copy(void *dest, const void *src, + const struct struct_member_t *member); +bool struct_var_eq(const void *a, const void *b, + const struct struct_member_t *member); +bool struct_var_ok(const void *object, + const struct struct_member_t *member); + +const char *struct_var_get_name(const struct struct_member_t *member); +const char *struct_var_get_typename(const struct struct_member_t *member); + +int struct_var_kvassign(void *object, const struct config_line_t *line, + char **errmsg, + const struct struct_member_t *member); +struct config_line_t *struct_var_kvencode( + const void *object, + const struct struct_member_t *member); + +#endif /* !defined(TOR_LIB_CONFMGT_STRUCTVAR_H) */ diff --git a/src/lib/confmgt/typedvar.c b/src/lib/confmgt/typedvar.c index fc45c44481..c2b9b45725 100644 --- a/src/lib/confmgt/typedvar.c +++ b/src/lib/confmgt/typedvar.c @@ -44,7 +44,7 @@ typed_var_assign_ex(void *target, const char *value, char **errmsg, const var_type_def_t *def) { if (BUG(!def)) - return -1; + return -1; // LCOV_EXCL_LINE // clear old value if needed. typed_var_free_ex(target, def); @@ -67,7 +67,7 @@ typed_var_kvassign_ex(void *target, const config_line_t *line, char **errmsg, const var_type_def_t *def) { if (BUG(!def)) - return -1; + return -1; // LCOV_EXCL_LINE if (def->fns->kv_parse) { // We do _not_ free the old value here, since linelist options @@ -86,7 +86,7 @@ void typed_var_free_ex(void *target, const var_type_def_t *def) { if (BUG(!def)) - return; + return; // LCOV_EXCL_LINE if (def->fns->clear) { def->fns->clear(target, def->params); } @@ -102,7 +102,7 @@ char * typed_var_encode_ex(const void *value, const var_type_def_t *def) { if (BUG(!def)) - return NULL; + return NULL; // LCOV_EXCL_LINE tor_assert(def->fns->encode); return def->fns->encode(value, def->params); } @@ -121,7 +121,7 @@ typed_var_kvencode_ex(const char *key, const void *value, const var_type_def_t *def) { if (BUG(!def)) - return NULL; + return NULL; // LCOV_EXCL_LINE if (def->fns->kv_encode) { return def->fns->kv_encode(key, value, def->params); } @@ -145,7 +145,7 @@ int typed_var_copy_ex(void *dest, const void *src, const var_type_def_t *def) { if (BUG(!def)) - return -1; + return -1; // LCOV_EXCL_LINE if (def->fns->copy) { // If we have been provided a copy fuction, use it. return def->fns->copy(dest, src, def); @@ -160,8 +160,10 @@ typed_var_copy_ex(void *dest, const void *src, const var_type_def_t *def) char *err = NULL; int rv = typed_var_assign_ex(dest, enc, &err, def); if (BUG(rv < 0)) { + // LCOV_EXCL_START log_warn(LD_BUG, "Encoded value %s was not parseable as a %s: %s", escaped(enc), def->name, err?err:""); + // LCOV_EXCL_STOP } tor_free(err); tor_free(enc); @@ -176,7 +178,7 @@ bool typed_var_eq_ex(const void *a, const void *b, const var_type_def_t *def) { if (BUG(!def)) - return false; + return false; // LCOV_EXCL_LINE if (def->fns->eq) { // Use a provided eq function if we got one. @@ -200,7 +202,7 @@ bool typed_var_ok_ex(const void *value, const var_type_def_t *def) { if (BUG(!def)) - return false; + return false; // LCOV_EXCL_LINE if (def->fns->ok) return def->fns->ok(value, def->params); |