forked from osmocom/wireshark
Change read_prefs() to use GStrings instead of (re)allocating memory
ourselves. This fixes a potential off-by-one error found by Steve Grubb. Add two new -G options: defaultprefs and currentprefs. The first dumps the default preferences to stdout and the second dumps the user's prefs to stdout. svn path=/trunk/; revision=14624
This commit is contained in:
parent
5a899bd97c
commit
5489ce999c
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <epan/proto.h>
|
#include <epan/proto.h>
|
||||||
#include <epan/packet.h>
|
#include <epan/packet.h>
|
||||||
|
#include <epan/prefs.h>
|
||||||
|
|
||||||
#include "clopts_common.h"
|
#include "clopts_common.h"
|
||||||
|
|
||||||
|
@ -41,6 +42,10 @@
|
||||||
void
|
void
|
||||||
handle_dashG_option(int argc, char **argv, char *progname)
|
handle_dashG_option(int argc, char **argv, char *progname)
|
||||||
{
|
{
|
||||||
|
char *gpf_path, *pf_path;
|
||||||
|
int gpf_open_errno, gpf_read_errno;
|
||||||
|
int pf_open_errno, pf_read_errno;
|
||||||
|
|
||||||
if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
|
if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
proto_registrar_dump_fields(1);
|
proto_registrar_dump_fields(1);
|
||||||
|
@ -57,7 +62,13 @@ handle_dashG_option(int argc, char **argv, char *progname)
|
||||||
proto_registrar_dump_values();
|
proto_registrar_dump_values();
|
||||||
else if (strcmp(argv[2], "decodes") == 0)
|
else if (strcmp(argv[2], "decodes") == 0)
|
||||||
dissector_dump_decodes();
|
dissector_dump_decodes();
|
||||||
else {
|
else if (strcmp(argv[2], "defaultprefs") == 0)
|
||||||
|
write_prefs(NULL);
|
||||||
|
else if (strcmp(argv[2], "currentprefs") == 0) {
|
||||||
|
read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
|
||||||
|
&pf_open_errno, &pf_read_errno, &pf_path);
|
||||||
|
write_prefs(NULL);
|
||||||
|
} else {
|
||||||
fprintf(stderr, "%s: Invalid \"%s\" option for -G flag\n", progname,
|
fprintf(stderr, "%s: Invalid \"%s\" option for -G flag\n", progname,
|
||||||
argv[2]);
|
argv[2]);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
75
epan/prefs.c
75
epan/prefs.c
|
@ -1169,22 +1169,18 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
{
|
{
|
||||||
enum { START, IN_VAR, PRE_VAL, IN_VAL, IN_SKIP };
|
enum { START, IN_VAR, PRE_VAL, IN_VAL, IN_SKIP };
|
||||||
int got_c, state = START;
|
int got_c, state = START;
|
||||||
static guint cur_pref_val_size;
|
static GString *cur_val = NULL;
|
||||||
static gchar* cur_val = NULL;
|
static GString *cur_var = NULL;
|
||||||
static guint cur_pref_var_size;
|
|
||||||
static gchar* cur_var = NULL;
|
|
||||||
gboolean got_val = FALSE;
|
gboolean got_val = FALSE;
|
||||||
gint var_len = 0, val_len = 0, fline = 1, pline = 1;
|
gint fline = 1, pline = 1;
|
||||||
gchar hint[] = "(saving your preferences once should remove this warning)";
|
gchar hint[] = "(saving your preferences once should remove this warning)";
|
||||||
|
|
||||||
if (! cur_val) {
|
if (! cur_val) {
|
||||||
cur_pref_val_size = 128;
|
cur_val = g_string_new("");
|
||||||
cur_val = g_malloc(cur_pref_val_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! cur_var) {
|
if (! cur_var) {
|
||||||
cur_pref_var_size = 128;
|
cur_var = g_string_new("");
|
||||||
cur_var = g_malloc(cur_pref_var_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((got_c = getc(pf)) != EOF) {
|
while ((got_c = getc(pf)) != EOF) {
|
||||||
|
@ -1193,25 +1189,13 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
fline++;
|
fline++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (var_len >= cur_pref_var_size) {
|
|
||||||
cur_pref_var_size *= 2;
|
|
||||||
cur_var = g_realloc(cur_var,cur_pref_val_size);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (val_len >= cur_pref_val_size) {
|
|
||||||
cur_pref_val_size *= 2;
|
|
||||||
cur_val = g_realloc(cur_val,cur_pref_val_size);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case START:
|
case START:
|
||||||
if (isalnum(got_c)) {
|
if (isalnum(got_c)) {
|
||||||
if (var_len > 0) {
|
if (cur_var->len > 0) {
|
||||||
if (got_val) {
|
if (got_val) {
|
||||||
cur_var[var_len] = '\0';
|
switch (pref_set_pair_fct(cur_var->str, cur_val->str)) {
|
||||||
cur_val[val_len] = '\0';
|
|
||||||
switch (pref_set_pair_fct(cur_var, cur_val)) {
|
|
||||||
|
|
||||||
case PREFS_SET_SYNTAX_ERR:
|
case PREFS_SET_SYNTAX_ERR:
|
||||||
g_warning ("%s line %d: Syntax error %s", pf_path, pline, hint);
|
g_warning ("%s line %d: Syntax error %s", pf_path, pline, hint);
|
||||||
|
@ -1219,7 +1203,7 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
|
|
||||||
case PREFS_SET_NO_SUCH_PREF:
|
case PREFS_SET_NO_SUCH_PREF:
|
||||||
g_warning ("%s line %d: No such preference \"%s\" %s", pf_path,
|
g_warning ("%s line %d: No such preference \"%s\" %s", pf_path,
|
||||||
pline, cur_var, hint);
|
pline, cur_var->str, hint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREFS_SET_OBSOLETE:
|
case PREFS_SET_OBSOLETE:
|
||||||
|
@ -1235,10 +1219,10 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
}
|
}
|
||||||
state = IN_VAR;
|
state = IN_VAR;
|
||||||
got_val = FALSE;
|
got_val = FALSE;
|
||||||
cur_var[0] = got_c;
|
g_string_truncate(cur_var, 0);
|
||||||
var_len = 1;
|
g_string_append_c(cur_var, got_c);
|
||||||
pline = fline;
|
pline = fline;
|
||||||
} else if (isspace(got_c) && var_len > 0 && got_val) {
|
} else if (isspace(got_c) && cur_var->len > 0 && got_val) {
|
||||||
state = PRE_VAL;
|
state = PRE_VAL;
|
||||||
} else if (got_c == '#') {
|
} else if (got_c == '#') {
|
||||||
state = IN_SKIP;
|
state = IN_SKIP;
|
||||||
|
@ -1248,38 +1232,33 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
break;
|
break;
|
||||||
case IN_VAR:
|
case IN_VAR:
|
||||||
if (got_c != ':') {
|
if (got_c != ':') {
|
||||||
cur_var[var_len] = got_c;
|
g_string_append_c(cur_var, got_c);
|
||||||
var_len++;
|
|
||||||
} else {
|
} else {
|
||||||
state = PRE_VAL;
|
state = PRE_VAL;
|
||||||
val_len = 0;
|
g_string_truncate(cur_val, 0);
|
||||||
got_val = TRUE;
|
got_val = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PRE_VAL:
|
case PRE_VAL:
|
||||||
if (!isspace(got_c)) {
|
if (!isspace(got_c)) {
|
||||||
state = IN_VAL;
|
state = IN_VAL;
|
||||||
cur_val[val_len] = got_c;
|
g_string_append_c(cur_val, got_c);
|
||||||
val_len++;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IN_VAL:
|
case IN_VAL:
|
||||||
if (got_c != '#') {
|
if (got_c != '#') {
|
||||||
cur_val[val_len] = got_c;
|
g_string_append_c(cur_val, got_c);
|
||||||
val_len++;
|
|
||||||
} else {
|
} else {
|
||||||
while (isspace((guchar)cur_val[val_len]) && val_len > 0)
|
while (isspace((guchar)cur_val->str[cur_val->len]) && cur_val->len > 0)
|
||||||
val_len--;
|
g_string_truncate(cur_val, cur_val->len - 1);
|
||||||
state = IN_SKIP;
|
state = IN_SKIP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (var_len > 0) {
|
if (cur_var->len > 0) {
|
||||||
if (got_val) {
|
if (got_val) {
|
||||||
cur_var[var_len] = '\0';
|
switch (pref_set_pair_fct(cur_var->str, cur_val->str)) {
|
||||||
cur_val[val_len] = '\0';
|
|
||||||
switch (pref_set_pair_fct(cur_var, cur_val)) {
|
|
||||||
|
|
||||||
case PREFS_SET_SYNTAX_ERR:
|
case PREFS_SET_SYNTAX_ERR:
|
||||||
g_warning ("%s line %d: Syntax error %s", pf_path, pline, hint);
|
g_warning ("%s line %d: Syntax error %s", pf_path, pline, hint);
|
||||||
|
@ -1287,7 +1266,7 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
|
||||||
|
|
||||||
case PREFS_SET_NO_SUCH_PREF:
|
case PREFS_SET_NO_SUCH_PREF:
|
||||||
g_warning ("%s line %d: No such preference \"%s\" %s", pf_path,
|
g_warning ("%s line %d: No such preference \"%s\" %s", pf_path,
|
||||||
pline, cur_var, hint);
|
pline, cur_var->str, hint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREFS_SET_OBSOLETE:
|
case PREFS_SET_OBSOLETE:
|
||||||
|
@ -2221,6 +2200,8 @@ write_module_prefs(gpointer data, gpointer user_data)
|
||||||
|
|
||||||
/* Write out "prefs" to the user's preferences file, and return 0.
|
/* Write out "prefs" to the user's preferences file, and return 0.
|
||||||
|
|
||||||
|
If the preferences file path is NULL, write to stdout.
|
||||||
|
|
||||||
If we got an error, stuff a pointer to the path of the preferences file
|
If we got an error, stuff a pointer to the path of the preferences file
|
||||||
into "*pf_path_return", and return the errno. */
|
into "*pf_path_return", and return the errno. */
|
||||||
int
|
int
|
||||||
|
@ -2237,10 +2218,14 @@ write_prefs(char **pf_path_return)
|
||||||
* so that duplication can be avoided with filter.c
|
* so that duplication can be avoided with filter.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pf_path = get_persconffile_path(PF_NAME, TRUE);
|
if (pf_path_return != NULL) {
|
||||||
if ((pf = fopen(pf_path, "w")) == NULL) {
|
pf_path = get_persconffile_path(PF_NAME, TRUE);
|
||||||
*pf_path_return = pf_path;
|
if ((pf = fopen(pf_path, "w")) == NULL) {
|
||||||
return errno;
|
*pf_path_return = pf_path;
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pf = stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs("# Configuration file for Ethereal " VERSION ".\n"
|
fputs("# Configuration file for Ethereal " VERSION ".\n"
|
||||||
|
|
Loading…
Reference in New Issue