summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-12-19 09:58:50 +0100
committerThomas Haller <thaller@redhat.com>2022-12-19 11:29:19 +0100
commitc990d6a81a5b0f267681304f215f28e3d2c03211 (patch)
tree60d5946b790bd3f637df3afaf606858b46efa856
parent0e63fe58a7ea38250d79214be22eb2eab3f524d6 (diff)
downloadNetworkManager-c990d6a81a5b0f267681304f215f28e3d2c03211.tar.gz
dhcp/dhclient: better handle "\r\n" line breaks in dhclient lease file
Splitting by any of "\r\n" and then joining the lines with "\n" leads to double-newlines. That's certainly wrong. Maybe we shouldn't care about "\r", I don't know why this was done. But handle it differently.
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient-utils.c36
-rw-r--r--src/core/dhcp/tests/test-dhcp-dhclient.c2
2 files changed, 22 insertions, 16 deletions
diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c
index c959430b4e..5bc135f02f 100644
--- a/src/core/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c
@@ -673,7 +673,7 @@ nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error)
return FALSE;
}
- lines = nm_strsplit_set_with_empty(contents, "\n\r");
+ lines = nm_strsplit_set_with_empty(contents, "\n");
}
s = g_string_sized_new(contents_len + 50);
@@ -684,27 +684,33 @@ nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error)
for (iter = lines; *iter; iter++) {
const char *str = *iter;
const char *l;
+ gboolean ends_with_r;
+ gsize l_len;
+ gsize prefix_len;
- /* If we find an uncommented DUID in the file, check if
- * equal to the one we are going to write: if so, no need
- * to update the lease file, otherwise skip the old DUID.
- */
- l = nm_str_skip_leading_spaces(str);
- if (g_str_has_prefix(l, DEFAULT_DUID_PREFIX)) {
- gs_strfreev char **split = NULL;
+ l = nm_str_skip_leading_spaces(str);
+ l_len = strlen(l);
+ prefix_len = l - str;
- split = g_strsplit(l, "\"", -1);
- if (split[0] && nm_streq0(split[1], escaped_duid))
- return TRUE;
+ ends_with_r = l_len > 0 && l[l_len - 1u] == '\r';
+ if (ends_with_r) {
+ ((char *) l)[--l_len] = '\0';
+ }
+ if (NM_STR_HAS_PREFIX(l, DEFAULT_DUID_PREFIX)) {
+ /* We always add our line on top. This line can be skipped. */
continue;
}
- if (str)
- g_string_append(s, str);
- /* avoid to add an extra '\n' at the end of file */
- if ((iter[1]) != NULL)
+ g_string_append_len(s, str, prefix_len);
+ g_string_append(s, l);
+ if (ends_with_r) {
+ g_string_append_c(s, '\r');
g_string_append_c(s, '\n');
+ } else if ((iter[1]) != NULL) {
+ /* avoid to add an extra '\n' at the end of file */
+ g_string_append_c(s, '\n');
+ }
}
}
diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c
index 6a94673d78..6daf689145 100644
--- a/src/core/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/core/dhcp/tests/test-dhcp-dhclient.c
@@ -1039,7 +1039,7 @@ test_write_duid(void)
"aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option "
"dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn "
"1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success "
- "\"success\";\n\n}\n");
+ "\"success\";\r\n}\n");
_check_duid(
_DUID(0xaa, 0xb, 0xcc, 0xd, 0xee, 0xe),