summaryrefslogtreecommitdiffstats
path: root/src/core/settings.c
diff options
context:
space:
mode:
authorMichael Brown2013-07-18 15:47:42 +0200
committerMichael Brown2013-07-19 16:29:21 +0200
commit129a70631a1b138f74bf0e2a7c6bdd1b564f8a10 (patch)
tree9e91437acc79b0015f98bc53255592fd7ea7520f /src/core/settings.c
parent[settings] Add fetchf_setting_copy() (diff)
downloadipxe-129a70631a1b138f74bf0e2a7c6bdd1b564f8a10.tar.gz
ipxe-129a70631a1b138f74bf0e2a7c6bdd1b564f8a10.tar.xz
ipxe-129a70631a1b138f74bf0e2a7c6bdd1b564f8a10.zip
[settings] Eliminate call to fetchf_named_setting() in expand_settings()
Use parse_setting_name() and fetchf_setting_copy() in expand_settings(), to eliminate the call to fetchf_named_setting(). This change also eliminates the potentially large stack-allocated buffer in expand_settings(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/settings.c')
-rw-r--r--src/core/settings.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/src/core/settings.c b/src/core/settings.c
index d3d15155..d5e02460 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -2014,15 +2014,18 @@ struct setting_type setting_type_busdevfn __setting_type = {
* eventually free() it.
*/
char * expand_settings ( const char *string ) {
+ struct settings *settings;
+ struct setting setting;
char *expstr;
char *start;
char *end;
char *head;
char *name;
char *tail;
- int setting_len;
- int new_len;
+ char *value;
char *tmp;
+ int new_len;
+ int rc;
/* Obtain temporary modifiable copy of string */
expstr = strdup ( string );
@@ -2052,27 +2055,27 @@ char * expand_settings ( const char *string ) {
*end = '\0';
tail = ( end + 1 );
- /* Determine setting length */
- setting_len = fetchf_named_setting ( name, NULL, 0, NULL, 0 );
- if ( setting_len < 0 )
- setting_len = 0; /* Treat error as empty setting */
-
- /* Read setting into temporary buffer */
- {
- char setting_buf[ setting_len + 1 ];
-
- setting_buf[0] = '\0';
- fetchf_named_setting ( name, NULL, 0, setting_buf,
- sizeof ( setting_buf ) );
-
- /* Construct expanded string and discard old string */
- tmp = expstr;
- new_len = asprintf ( &expstr, "%s%s%s",
- head, setting_buf, tail );
- free ( tmp );
- if ( new_len < 0 )
- return NULL;
+ /* Expand setting */
+ if ( ( rc = parse_setting_name ( name, find_child_settings,
+ &settings,
+ &setting ) ) != 0 ) {
+ /* Treat invalid setting names as empty */
+ value = NULL;
+ } else {
+ /* Fetch and format setting value. Ignore
+ * errors; treat non-existent settings as empty.
+ */
+ fetchf_setting_copy ( settings, &setting, &value );
}
+
+ /* Construct expanded string and discard old string */
+ tmp = expstr;
+ new_len = asprintf ( &expstr, "%s%s%s",
+ head, ( value ? value : "" ), tail );
+ free ( value );
+ free ( tmp );
+ if ( new_len < 0 )
+ return NULL;
}
return expstr;