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 */
|
/* remove escaped characters in place */
|
||||||
void
|
const char *
|
||||||
svUnescape (char *s)
|
svUnescape (const char *value, char **to_free)
|
||||||
{
|
{
|
||||||
size_t len, idx_rd = 0, idx_wr = 0;
|
size_t len, idx_rd = 0, idx_wr = 0;
|
||||||
char c;
|
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);
|
len = strlen (s);
|
||||||
if (len < 2) {
|
if (len < 2) {
|
||||||
if (s[0] == '\\')
|
if (s[0] == '\\')
|
||||||
s[0] = '\0';
|
s[0] = '\0';
|
||||||
return;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
|
if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
|
||||||
if (len == 2) {
|
if (len == 2) {
|
||||||
s[0] = '\0';
|
s[0] = '\0';
|
||||||
return;
|
return s;
|
||||||
}
|
}
|
||||||
if (len == 3) {
|
if (len == 3) {
|
||||||
if (s[1] == '\\') {
|
if (s[1] == '\\') {
|
||||||
@@ -175,7 +183,7 @@ svUnescape (char *s)
|
|||||||
s[0] = s[1];
|
s[0] = s[1];
|
||||||
s[1] = '\0';
|
s[1] = '\0';
|
||||||
}
|
}
|
||||||
return;
|
return s;
|
||||||
}
|
}
|
||||||
s[--len] = '\0';
|
s[--len] = '\0';
|
||||||
idx_rd = 1;
|
idx_rd = 1;
|
||||||
@@ -184,10 +192,10 @@ svUnescape (char *s)
|
|||||||
char *p = strchr (s, '\\');
|
char *p = strchr (s, '\\');
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return;
|
return s;
|
||||||
if (p[1] == '\0') {
|
if (p[1] == '\0') {
|
||||||
p[0] = '\0';
|
p[0] = '\0';
|
||||||
return;
|
return s;
|
||||||
}
|
}
|
||||||
idx_wr = idx_rd = (p - s);
|
idx_wr = idx_rd = (p - s);
|
||||||
}
|
}
|
||||||
@@ -199,7 +207,7 @@ svUnescape (char *s)
|
|||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
if (s[idx_rd] == '\0') {
|
if (s[idx_rd] == '\0') {
|
||||||
s[idx_wr] = '\0';
|
s[idx_wr] = '\0';
|
||||||
return;
|
return s;
|
||||||
}
|
}
|
||||||
s[idx_wr++] = s[idx_rd++];
|
s[idx_wr++] = s[idx_rd++];
|
||||||
continue;
|
continue;
|
||||||
@@ -207,6 +215,7 @@ svUnescape (char *s)
|
|||||||
s[idx_wr++] = c;
|
s[idx_wr++] = c;
|
||||||
}
|
}
|
||||||
s[idx_wr] = '\0';
|
s[idx_wr] = '\0';
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -352,7 +361,7 @@ char *
|
|||||||
svGetValue (shvarFile *s, const char *key)
|
svGetValue (shvarFile *s, const char *key)
|
||||||
{
|
{
|
||||||
const char *line_val;
|
const char *line_val;
|
||||||
char *value;
|
char *copied;
|
||||||
|
|
||||||
g_return_val_if_fail (s != NULL, NULL);
|
g_return_val_if_fail (s != NULL, NULL);
|
||||||
g_return_val_if_fail (key != NULL, NULL);
|
g_return_val_if_fail (key != NULL, NULL);
|
||||||
@@ -361,9 +370,8 @@ svGetValue (shvarFile *s, const char *key)
|
|||||||
if (!line_val)
|
if (!line_val)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
value = g_strchomp (g_strdup (line_val));
|
line_val = svUnescape (line_val, &copied);
|
||||||
svUnescape (value);
|
return copied ?: g_strdup (line_val);
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value associated with the key, and leave the current pointer
|
/* 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. */
|
/* Close the file descriptor (if open) and free the shvarFile. */
|
||||||
void svCloseFile (shvarFile *s);
|
void svCloseFile (shvarFile *s);
|
||||||
|
|
||||||
/* Return @s unmodified or an escaped string */
|
|
||||||
const char *svEscape (const char *s, char **to_free);
|
const char *svEscape (const char *s, char **to_free);
|
||||||
|
const char *svUnescape (const char *s, char **to_free);
|
||||||
/* Unescape a string in-place */
|
|
||||||
void svUnescape (char *s);
|
|
||||||
|
|
||||||
#endif /* _SHVAR_H */
|
#endif /* _SHVAR_H */
|
||||||
|
@@ -8695,50 +8695,13 @@ test_read_team_port_empty_config (void)
|
|||||||
g_object_unref (connection);
|
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
|
static void
|
||||||
test_svUnescape_assert (const char *str)
|
test_svUnescape_assert (const char *str)
|
||||||
{
|
{
|
||||||
char *s1 = g_strdup (str);
|
gs_free char *to_free = NULL;
|
||||||
char *s2 = g_strdup (str);
|
const char *s;
|
||||||
|
|
||||||
svUnescape (s1);
|
s = svUnescape (str, &to_free);
|
||||||
svUnescape_On2 (s2);
|
|
||||||
|
|
||||||
g_assert_cmpstr (s1, ==, s2);
|
|
||||||
|
|
||||||
g_free (s1);
|
|
||||||
g_free (s2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user