Report syntax errors in UAT prefs parsing
authorPeter Wu <peter@lekensteyn.nl>
Wed, 24 May 2017 22:28:45 +0000 (00:28 +0200)
committerMichael Mann <mmann78@netscape.net>
Fri, 26 May 2017 17:31:01 +0000 (17:31 +0000)
Add the cause for a syntax error while parsing UATs. Example output:

    $ tshark -ouat:ssl_keys:,
    tshark: Invalid -o flag "uat:ssl_keys:,": ssl_keys:1: No IP address given.
    $ tshark -ouat:unknown:,
    tshark: Invalid -o flag "uat:unknown:,": Unknown preference

Change-Id: I549406c4e31a81d29f487ef47bdb3c22da084947
Reviewed-on: https://code.wireshark.org/review/21748
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Reviewed-by: Michael Mann <mmann78@netscape.net>
epan/prefs.c
epan/prefs.h
rawshark.c
sharkd_session.c
tfshark.c
tshark.c
ui/commandline.c

index 18fdc15c312ae13a2138ccef21386a35aff439df..35ff3fa2a297e5cdf9526bd2fd26dfaf87503758 100644 (file)
@@ -4510,10 +4510,9 @@ read_prefs_file(const char *pf_path, FILE *pf,
  * a valid uat entry.
  */
 static gboolean
-prefs_set_uat_pref(char *uat_entry) {
+prefs_set_uat_pref(char *uat_entry, char **errmsg) {
     gchar *p, *colonp;
     uat_t *uat;
-    gchar *err = NULL;
     gboolean ret;
 
     colonp = strchr(uat_entry, ':');
@@ -4543,11 +4542,11 @@ prefs_set_uat_pref(char *uat_entry) {
     uat = uat_find(uat_entry);
     *colonp = ':';
     if (uat == NULL) {
+        *errmsg = g_strdup("Unknown preference");
         return FALSE;
     }
 
-    ret = uat_load_str(uat, p, &err);
-    g_free(err);
+    ret = uat_load_str(uat, p, errmsg);
     return ret;
 }
 
@@ -4558,7 +4557,7 @@ prefs_set_uat_pref(char *uat_entry) {
  * in some fashion.
  */
 prefs_set_pref_e
-prefs_set_pref(char *prefarg)
+prefs_set_pref(char *prefarg, char **errmsg)
 {
     gchar *p, *colonp;
     prefs_set_pref_e ret;
@@ -4573,6 +4572,8 @@ prefs_set_pref(char *prefarg)
     mgcp_tcp_port_count = -1;
     mgcp_udp_port_count = -1;
 
+    *errmsg = NULL;
+
     colonp = strchr(prefarg, ':');
     if (colonp == NULL)
         return PREFS_SET_SYNTAX_ERR;
@@ -4599,7 +4600,7 @@ prefs_set_pref(char *prefarg)
     if (strcmp(prefarg, "uat")) {
         ret = set_pref(prefarg, p, NULL, TRUE);
     } else {
-        ret = prefs_set_uat_pref(p) ? PREFS_SET_OK : PREFS_SET_SYNTAX_ERR;
+        ret = prefs_set_uat_pref(p, errmsg) ? PREFS_SET_OK : PREFS_SET_SYNTAX_ERR;
     }
     *colonp = ':';    /* put the colon back */
     return ret;
index 85d66b6cf658a6552849064173a1ab512759eb80..e757a25533213ae54294af800b3715216100ee8f 100644 (file)
@@ -575,14 +575,8 @@ extern e_prefs *read_prefs(void);
    into "*pf_path_return", and return the errno. */
 WS_DLL_PUBLIC int write_prefs(char **);
 
-/*
- * Given a string of the form "<pref name>:<pref value>", as might appear
- * as an argument to a "-o" option, parse it and set the preference in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- *
- * XXX - should supply, for syntax errors, a detailed explanation of
- * the syntax error.
+/**
+ * Result of setting a preference.
  */
 typedef enum {
     PREFS_SET_OK,               /* succeeded */
@@ -591,7 +585,16 @@ typedef enum {
     PREFS_SET_OBSOLETE          /* preference used to exist but no longer does */
 } prefs_set_pref_e;
 
-WS_DLL_PUBLIC prefs_set_pref_e prefs_set_pref(char *prefarg);
+/*
+ * Given a string of the form "<pref name>:<pref value>", as might appear
+ * as an argument to a "-o" option, parse it and set the preference in
+ * question.  Return an indication of whether it succeeded or failed
+ * in some fashion.
+ *
+ * For syntax errors (return value PREFS_SET_SYNTAX_ERR), details (when
+ * available) are written into "errmsg" which must be freed with g_free.
+ */
+WS_DLL_PUBLIC prefs_set_pref_e prefs_set_pref(char *prefarg, char **errmsg);
 
 /*
  * Get or set a preference's obsolete status. These can be used to make a
index bcb2f8ca5d9bdb044613afe8cbeb161dab661859..6454ab1a78d4dec24edb8440676d64a62fa82327 100644 (file)
@@ -370,6 +370,7 @@ set_link_type(const char *lt_arg) {
     long val;
     dissector_handle_t dhandle;
     GString *pref_str;
+    char *errmsg = NULL;
 
     if (!spec_ptr)
         return FALSE;
@@ -410,8 +411,9 @@ set_link_type(const char *lt_arg) {
             g_string_append_printf(pref_str,
                                    "\"User 0 (DLT=147)\",\"%s\",\"0\",\"\",\"0\",\"\"",
                                    spec_ptr);
-            if (prefs_set_pref(pref_str->str) != PREFS_SET_OK) {
+            if (prefs_set_pref(pref_str->str, &errmsg) != PREFS_SET_OK) {
                 g_string_free(pref_str, TRUE);
+                g_free(errmsg);
                 return FALSE;
             }
             g_string_free(pref_str, TRUE);
@@ -620,13 +622,18 @@ main(int argc, char *argv[])
                 }
                 break;
             case 'o':        /* Override preference from command line */
-                switch (prefs_set_pref(optarg)) {
+            {
+                char *errmsg = NULL;
+
+                switch (prefs_set_pref(optarg, &errmsg)) {
 
                     case PREFS_SET_OK:
                         break;
 
                     case PREFS_SET_SYNTAX_ERR:
-                        cmdarg_err("Invalid -o flag \"%s\"", optarg);
+                        cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
+                                errmsg ? ": " : "", errmsg ? errmsg : "");
+                        g_free(errmsg);
                         ret = INVALID_OPTION;
                         goto clean_exit;
                         break;
@@ -639,6 +646,7 @@ main(int argc, char *argv[])
                         break;
                 }
                 break;
+            }
             case 'p':        /* Expect pcap_pkthdr packet headers, which may have 64-bit timestamps */
                 want_pcap_pkthdr = TRUE;
                 break;
index 3ea1e3f1252de17e57603895db0c9ced09c34704..6dc6f3b84d79e23ebc19eb39518da730c0bcad35 100644 (file)
@@ -3073,6 +3073,7 @@ sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)
        const char *tok_name = json_find_attr(buf, tokens, count, "name");
        const char *tok_value = json_find_attr(buf, tokens, count, "value");
        char pref[4096];
+       char *errmsg = NULL;
 
        prefs_set_pref_e ret;
 
@@ -3081,8 +3082,15 @@ sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)
 
        ws_snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);
 
-       ret = prefs_set_pref(pref);
-       printf("{\"err\":%d}\n", ret);
+       ret = prefs_set_pref(pref, &errmsg);
+       printf("{\"err\":%d", ret);
+       if (errmsg) {
+               /* Add error message for some syntax errors. */
+               printf(",\"errmsg\":");
+               json_puts_string(errmsg);
+       }
+       printf("}\n");
+       g_free(errmsg);
 }
 
 struct sharkd_session_process_dumpconf_data
index bad0ab3b469d701b48c2cfaf86bd43c0c4b165a9..b91afb62729c8ef53a642385d9a2ec0bb40b0ab7 100644 (file)
--- a/tfshark.c
+++ b/tfshark.c
@@ -689,13 +689,18 @@ main(int argc, char *argv[])
       line_buffered = TRUE;
       break;
     case 'o':        /* Override preference from command line */
-      switch (prefs_set_pref(optarg)) {
+    {
+      char *errmsg = NULL;
+
+      switch (prefs_set_pref(optarg, &errmsg)) {
 
       case PREFS_SET_OK:
         break;
 
       case PREFS_SET_SYNTAX_ERR:
-        cmdarg_err("Invalid -o flag \"%s\"", optarg);
+        cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
+            errmsg ? ": " : "", errmsg ? errmsg : "");
+        g_free(errmsg);
         return 1;
         break;
 
@@ -707,6 +712,7 @@ main(int argc, char *argv[])
         break;
       }
       break;
+    }
     case 'q':        /* Quiet */
       quiet = TRUE;
       break;
index e4d4551c9603bcaf62d4c96161fbcb784cf9c302..c0fff8768637edbb8fe931e5c8993ac9f1c2f533 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -1208,13 +1208,18 @@ main(int argc, char *argv[])
 #endif
       break;
     case 'o':        /* Override preference from command line */
-      switch (prefs_set_pref(optarg)) {
+    {
+      char *errmsg = NULL;
+
+      switch (prefs_set_pref(optarg, &errmsg)) {
 
       case PREFS_SET_OK:
         break;
 
       case PREFS_SET_SYNTAX_ERR:
-        cmdarg_err("Invalid -o flag \"%s\"", optarg);
+        cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
+            errmsg ? ": " : "", errmsg ? errmsg : "");
+        g_free(errmsg);
         exit_status = INVALID_OPTION;
         goto clean_exit;
         break;
@@ -1227,6 +1232,7 @@ main(int argc, char *argv[])
         break;
       }
       break;
+    }
     case 'q':        /* Quiet */
       quiet = TRUE;
       break;
index 127bb6a4af91d0fedb5a68b111e17c2316b78eed..fc4be160101749f515a220bf0abe6a0bed7b2af3 100644 (file)
@@ -471,11 +471,16 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
 #endif
                 break;
             case 'o':        /* Override preference from command line */
-                switch (prefs_set_pref(optarg)) {
+            {
+                char *errmsg = NULL;
+
+                switch (prefs_set_pref(optarg, &errmsg)) {
                     case PREFS_SET_OK:
                         break;
                     case PREFS_SET_SYNTAX_ERR:
-                        cmdarg_err("Invalid -o flag \"%s\"", optarg);
+                        cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
+                                errmsg ? ": " : "", errmsg ? errmsg : "");
+                        g_free(errmsg);
                         exit(1);
                         break;
                     case PREFS_SET_NO_SUCH_PREF:
@@ -507,6 +512,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
                         g_assert_not_reached();
                 }
                 break;
+            }
             case 'P':
                 /* Path settings were already processed just ignore them this time*/
                 break;