ifcfg-rh: refactor svUnescape()
Move the g_strchomp() inside svUnescape(). It is part of the escaping process (although of course wrong to do, because it accepts "FOO= bar". That will be fixed later). Thereby, change the signature to allow in the future to do unescape without additional copy.
This commit is contained in:
@@ -150,23 +150,31 @@ svEscape (const char *s, char **to_free)
|
||||
}
|
||||
|
||||
/* remove escaped characters in place */
|
||||
void
|
||||
svUnescape (char *s)
|
||||
const char *
|
||||
svUnescape (const char *value, char **to_free)
|
||||
{
|
||||
size_t len, idx_rd = 0, idx_wr = 0;
|
||||
char c;
|
||||
char *s;
|
||||
|
||||
nm_assert (value);
|
||||
nm_assert (to_free);
|
||||
|
||||
/* TODO: avoid copying the string if there is nothing to do. */
|
||||
s = g_strchomp (g_strdup (value));
|
||||
*to_free = s;
|
||||
|
||||
len = strlen (s);
|
||||
if (len < 2) {
|
||||
if (s[0] == '\\')
|
||||
s[0] = '\0';
|
||||
return;
|
||||
return s;
|
||||
}
|
||||
|
||||
if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
|
||||
if (len == 2) {
|
||||
s[0] = '\0';
|
||||
return;
|
||||
return s;
|
||||
}
|
||||
if (len == 3) {
|
||||
if (s[1] == '\\') {
|
||||
@@ -175,7 +183,7 @@ svUnescape (char *s)
|
||||
s[0] = s[1];
|
||||
s[1] = '\0';
|
||||
}
|
||||
return;
|
||||
return s;
|
||||
}
|
||||
s[--len] = '\0';
|
||||
idx_rd = 1;
|
||||
@@ -184,10 +192,10 @@ svUnescape (char *s)
|
||||
char *p = strchr (s, '\\');
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
return s;
|
||||
if (p[1] == '\0') {
|
||||
p[0] = '\0';
|
||||
return;
|
||||
return s;
|
||||
}
|
||||
idx_wr = idx_rd = (p - s);
|
||||
}
|
||||
@@ -199,7 +207,7 @@ svUnescape (char *s)
|
||||
if (c == '\\') {
|
||||
if (s[idx_rd] == '\0') {
|
||||
s[idx_wr] = '\0';
|
||||
return;
|
||||
return s;
|
||||
}
|
||||
s[idx_wr++] = s[idx_rd++];
|
||||
continue;
|
||||
@@ -207,6 +215,7 @@ svUnescape (char *s)
|
||||
s[idx_wr++] = c;
|
||||
}
|
||||
s[idx_wr] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -352,7 +361,7 @@ char *
|
||||
svGetValue (shvarFile *s, const char *key)
|
||||
{
|
||||
const char *line_val;
|
||||
char *value;
|
||||
char *copied;
|
||||
|
||||
g_return_val_if_fail (s != NULL, NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
@@ -361,9 +370,8 @@ svGetValue (shvarFile *s, const char *key)
|
||||
if (!line_val)
|
||||
return NULL;
|
||||
|
||||
value = g_strchomp (g_strdup (line_val));
|
||||
svUnescape (value);
|
||||
return value;
|
||||
line_val = svUnescape (line_val, &copied);
|
||||
return copied ?: g_strdup (line_val);
|
||||
}
|
||||
|
||||
/* Get the value associated with the key, and leave the current pointer
|
||||
|
@@ -81,10 +81,7 @@ gboolean svWriteFile (shvarFile *s, int mode, GError **error);
|
||||
/* Close the file descriptor (if open) and free the shvarFile. */
|
||||
void svCloseFile (shvarFile *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);
|
||||
const char *svUnescape (const char *s, char **to_free);
|
||||
|
||||
#endif /* _SHVAR_H */
|
||||
|
@@ -8695,50 +8695,13 @@ test_read_team_port_empty_config (void)
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
/* Old algorithm for "remove escaped characters in place".
|
||||
*
|
||||
* This function is obsolete because it has O(n^2) runtime
|
||||
* complexity and got replaced. Keep it here for testing,
|
||||
* that both functions behave identical.
|
||||
**/
|
||||
static void
|
||||
svUnescape_On2 (char *s)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
len = strlen(s);
|
||||
if (len >= 2 && (s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
|
||||
i = len - 2;
|
||||
if (i == 0)
|
||||
s[0] = '\0';
|
||||
else {
|
||||
memmove(s, s+1, i);
|
||||
s[i+1] = '\0';
|
||||
len = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (s[i] == '\\') {
|
||||
memmove(s+i, s+i+1, len-(i+1));
|
||||
len--;
|
||||
}
|
||||
s[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_svUnescape_assert (const char *str)
|
||||
{
|
||||
char *s1 = g_strdup (str);
|
||||
char *s2 = g_strdup (str);
|
||||
gs_free char *to_free = NULL;
|
||||
const char *s;
|
||||
|
||||
svUnescape (s1);
|
||||
svUnescape_On2 (s2);
|
||||
|
||||
g_assert_cmpstr (s1, ==, s2);
|
||||
|
||||
g_free (s1);
|
||||
g_free (s2);
|
||||
s = svUnescape (str, &to_free);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Reference in New Issue
Block a user