summaryrefslogtreecommitdiffstats
path: root/src/core/settings.c
diff options
context:
space:
mode:
authorMichael Brown2013-07-18 16:48:29 +0200
committerMichael Brown2013-07-18 16:58:05 +0200
commit78178608e978f42c12e12dfd32072e3e9cb85bf9 (patch)
tree4150a1495cdc4cc2da34422367ba8cd4a7ffcf44 /src/core/settings.c
parent[settings] Avoid potentially large stack allocations (diff)
downloadipxe-78178608e978f42c12e12dfd32072e3e9cb85bf9.tar.gz
ipxe-78178608e978f42c12e12dfd32072e3e9cb85bf9.tar.xz
ipxe-78178608e978f42c12e12dfd32072e3e9cb85bf9.zip
[settings] Remove temporary name buffer parameter from parse_setting_name()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/settings.c')
-rw-r--r--src/core/settings.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/src/core/settings.c b/src/core/settings.c
index 891e7b3a..6f57891b 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -1189,27 +1189,27 @@ static struct setting_type * find_setting_type ( const char *name ) {
* @v settings Settings block to fill in
* @v setting Setting to fill in
* @v default_type Default type to use, if none specified
- * @v tmp_name Buffer for copy of setting name
* @ret rc Return status code
*
* Interprets a name of the form
* "[settings_name/]tag_name[:type_name]" and fills in the appropriate
* fields.
*
- * The @c tmp_name buffer must be large enough to hold a copy of the
- * setting name.
+ * Note that on success, this function will have modified the original
+ * setting @c name.
*/
static int
-parse_setting_name ( const char *name,
- struct settings * ( * get_child ) ( struct settings *,
- const char * ),
+parse_setting_name ( char *name,
+ struct settings * ( * get_child )
+ ( struct settings *settings,
+ const char *name ),
struct settings **settings, struct setting *setting,
- struct setting_type *default_type,
- char *tmp_name ) {
+ struct setting_type *default_type ) {
char *settings_name;
char *setting_name;
char *type_name;
struct setting *predefined;
+ int rc;
/* Set defaults */
*settings = &settings_root;
@@ -1218,12 +1218,11 @@ parse_setting_name ( const char *name,
setting->type = default_type;
/* Split name into "[settings_name/]setting_name[:type_name]" */
- strcpy ( tmp_name, name );
- if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
+ if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) {
*(setting_name++) = 0;
- settings_name = tmp_name;
+ settings_name = name;
} else {
- setting_name = tmp_name;
+ setting_name = name;
settings_name = NULL;
}
if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
@@ -1235,7 +1234,8 @@ parse_setting_name ( const char *name,
if ( *settings == NULL ) {
DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
settings_name, name );
- return -ENODEV;
+ rc = -ENODEV;
+ goto err;
}
}
@@ -1257,11 +1257,20 @@ parse_setting_name ( const char *name,
if ( setting->type == NULL ) {
DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
type_name, name );
- return -ENOTSUP;
+ rc = -ENOTSUP;
+ goto err;
}
}
return 0;
+
+ err:
+ /* Restore original name */
+ if ( settings_name )
+ *( setting_name - 1 ) = '/';
+ if ( type_name )
+ *( type_name - 1 ) = ':';
+ return rc;
}
/**
@@ -1299,10 +1308,13 @@ int store_named_setting ( const char *name, struct setting_type *default_type,
char tmp_name[ strlen ( name ) + 1 ];
int rc;
+ /* Create modifiable copy of setting name */
+ strcpy ( tmp_name, name );
+
/* Parse setting name */
- if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
- &settings, &setting, default_type,
- tmp_name ) ) != 0 )
+ if ( ( rc = parse_setting_name ( tmp_name, autovivify_child_settings,
+ &settings, &setting,
+ default_type ) ) != 0 )
return rc;
/* Store setting */
@@ -1327,10 +1339,13 @@ int storef_named_setting ( const char *name, struct setting_type *default_type,
char tmp_name[ strlen ( name ) + 1 ];
int rc;
+ /* Create modifiable copy of setting name */
+ strcpy ( tmp_name, name );
+
/* Parse setting name */
- if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
- &settings, &setting, default_type,
- tmp_name ) ) != 0 )
+ if ( ( rc = parse_setting_name ( tmp_name, autovivify_child_settings,
+ &settings, &setting,
+ default_type ) ) != 0 )
return rc;
/* Store setting */
@@ -1360,9 +1375,12 @@ int fetchf_named_setting ( const char *name,
int len;
int rc;
+ /* Create modifiable copy of setting name */
+ strcpy ( tmp_name, name );
+
/* Parse setting name */
- if ( ( rc = parse_setting_name ( name, find_child_settings, &settings,
- &setting, NULL, tmp_name ) ) != 0 )
+ if ( ( rc = parse_setting_name ( tmp_name, find_child_settings,
+ &settings, &setting, NULL ) ) != 0 )
return rc;
/* Fetch setting */