# HG changeset patch # User zas_ # Date 1213310612 0 # Node ID 4a913f093f56c084aeae5c0eab188e0d475aac4f # Parent ed82f5bf8082b16a2af27b668b5016c965fe59f4 load_options_from(): - do not copy option name and value anywhere, only copy value_all to a separate buffer - allow more relaxed syntax on read, so we can correctly read option name and value even if user made some errors like replacing ':' by '=' or inserting a space before ':'. - minor aesthetical changes diff -r ed82f5bf8082 -r 4a913f093f56 src/rcfile.c --- a/src/rcfile.c Thu Jun 12 21:21:32 2008 +0000 +++ b/src/rcfile.c Thu Jun 12 22:43:32 2008 +0000 @@ -49,7 +49,7 @@ if (l == 0) return retval; - while (c < l && text[c] !='"') c++; + while (c < l && text[c] != '"') c++; if (text[c] == '"') { gint e; @@ -81,7 +81,7 @@ * read a line without quotes too */ { c = 0; - while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++; + while (c < l && text[c] != '\n' && !g_ascii_isspace(text[c])) c++; if (c != 0) { retval = g_strndup(text, c); @@ -642,16 +642,16 @@ return TRUE; } - +#define OPTION_READ_BUFFER_SIZE 1024 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options) { FILE *f; gchar *rc_pathl; - gchar s_buf[1024]; - gchar option[1024]; - gchar value[1024]; - gchar value_all[1024]; + gchar s_buf[OPTION_READ_BUFFER_SIZE]; + gchar value_all[OPTION_READ_BUFFER_SIZE]; + gchar *option; + gchar *value; gint i; rc_pathl = path_from_utf8(utf8_path); @@ -661,23 +661,31 @@ while (fgets(s_buf, sizeof(s_buf), f)) { - gchar *option_start, *value_start; + gchar *value_end; gchar *p = s_buf; + /* skip empty lines and comments */ while (g_ascii_isspace(*p)) p++; if (!*p || *p == '\n' || *p == '#') continue; - option_start = p; - while (*p && *p != ':') p++; + + /* parse option name */ + option = p; + while (g_ascii_isalnum(*p) || *p == '_' || *p == '.') p++; if (!*p) continue; *p = '\0'; p++; - strncpy(option, option_start, sizeof(option)); - while (g_ascii_isspace(*p)) p++; - value_start = p; - strncpy(value_all, value_start, sizeof(value_all)); + + /* search for value start, name and value are normally separated by ': ' + * but we allow relaxed syntax here, so '=', ':=' or just a tab will work too */ + while (*p == ':' || g_ascii_isspace(*p) || *p == '=') p++; + value = p; + while (*p && !g_ascii_isspace(*p) && *p != '\n') p++; - *p = '\0'; - strncpy(value, value_start, sizeof(value)); + value_end = p; /* value part up to the first whitespace or end of line */ + while (*p != '\0') p++; + memcpy(value_all, value, 1 + p - value); + + *value_end = '\0'; #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue; #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;