From 32871deecc127cfa35dd5fc212e63d2e5bd468e2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 20 May 2015 13:54:25 +0200 Subject: [PATCH] ifcfg-rh: refactor svSetValue() and svEscape() not to clone string needlessly In the most cases we don't expect that our values need escaping. No need to do an additional copy of the unmodified string. --- src/settings/plugins/ifcfg-rh/shvar.c | 35 +++++++++++++------------- src/settings/plugins/ifcfg-rh/shvar.h | 4 +-- src/settings/plugins/ifcfg-rh/writer.c | 10 +++++--- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index ed12683072..0aa9569608 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -36,6 +36,7 @@ #include "shvar.h" +#include "gsystem-local-alloc.h" #include "nm-core-internal.h" #include "nm-logging.h" @@ -206,8 +207,8 @@ static const char escapees[] = "\"'\\$~`"; /* must be escaped */ static const char spaces[] = " \t|&;()<>"; /* only require "" */ static const char newlines[] = "\n\r"; /* will be removed */ -char * -svEscape (const char *s) +const char * +svEscape (const char *s, char **to_free) { char *new; int i, j, mangle = 0, space = 0, newline = 0; @@ -223,8 +224,10 @@ svEscape (const char *s) if (strchr (newlines, s[i])) newline++; } - if (!mangle && !space && !newline) - return strdup (s); + if (!mangle && !space && !newline) { + *to_free = NULL; + return s; + } newlen = slen + mangle - newline + 3; /* 3 is extra ""\0 */ new = g_malloc (newlen); @@ -243,6 +246,7 @@ svEscape (const char *s) new[j++] = '\0'; g_assert (j == slen + mangle - newline + 3); + *to_free = new; return new; } @@ -354,17 +358,19 @@ svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 m void svSetValue (shvarFile *s, const char *key, const char *value, gboolean verbatim) { - char *newval = NULL, *oldval = NULL; + gs_free char *newval_free = NULL; + gs_free char *oldval = NULL; + const char *newval; char *keyValue; g_return_if_fail (s != NULL); g_return_if_fail (key != NULL); /* value may be NULL */ - if (value) - newval = verbatim ? g_strdup (value) : svEscape (value); - keyValue = g_strdup_printf ("%s=%s", key, newval ? newval : ""); - + if (!value || verbatim) + newval = value; + else + newval = svEscape (value, &newval_free); oldval = svGetValue (s, key, FALSE); if (!newval || !newval[0]) { @@ -376,15 +382,15 @@ svSetValue (shvarFile *s, const char *key, const char *value, gboolean verbatim) g_list_free_1 (s->current); s->modified = TRUE; } - g_free (keyValue); - goto end; + return; } + keyValue = g_strdup_printf ("%s=%s", key, newval); if (!oldval) { /* append line */ s->lineList = g_list_append (s->lineList, keyValue); s->modified = TRUE; - goto end; + return; } if (strcmp (oldval, newval) != 0) { @@ -397,11 +403,6 @@ svSetValue (shvarFile *s, const char *key, const char *value, gboolean verbatim) s->modified = TRUE; } else g_free (keyValue); - - end: - g_free (newval); - g_free (oldval); - return; } /* Write the current contents iff modified. Returns FALSE on error diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index b2a2f2636e..28634ddd5d 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -84,8 +84,8 @@ gboolean svWriteFile (shvarFile *s, int mode, GError **error); /* Close the file descriptor (if open) and free the shvarFile. */ void svCloseFile (shvarFile *s); -/* Return a new escaped string */ -char *svEscape (const char *s); +/* Return @s unmodified or an escaped string */ +const char *svEscape (const char *s, char **to_free); /* Unescape a string in-place */ void svUnescape (char *s); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 27f1c70599..9924eb0f06 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -889,20 +889,22 @@ write_wireless_setting (NMConnection *connection, svSetValue (ifcfg, "ESSID", str->str, TRUE); g_string_free (str, TRUE); } else { + const char *tmp_escaped; + /* Printable SSIDs always get quoted */ memset (buf, 0, sizeof (buf)); memcpy (buf, ssid_data, ssid_len); - tmp = svEscape (buf); + tmp_escaped = svEscape (buf, &tmp); /* svEscape will usually quote the string, but just for consistency, * if svEscape doesn't quote the ESSID, we quote it ourselves. */ - if (tmp[0] != '"' && tmp[strlen (tmp) - 1] != '"') { - tmp2 = g_strdup_printf ("\"%s\"", tmp); + if (tmp_escaped[0] != '"' && tmp_escaped[strlen (tmp_escaped) - 1] != '"') { + tmp2 = g_strdup_printf ("\"%s\"", tmp_escaped); svSetValue (ifcfg, "ESSID", tmp2, TRUE); g_free (tmp2); } else - svSetValue (ifcfg, "ESSID", tmp, TRUE); + svSetValue (ifcfg, "ESSID", tmp_escaped, TRUE); g_free (tmp); }