diff options
author | Thomas Haller <thaller@redhat.com> | 2022-12-19 09:58:50 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-12-19 11:29:19 +0100 |
commit | c990d6a81a5b0f267681304f215f28e3d2c03211 (patch) | |
tree | 60d5946b790bd3f637df3afaf606858b46efa856 | |
parent | 0e63fe58a7ea38250d79214be22eb2eab3f524d6 (diff) | |
download | NetworkManager-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.c | 36 | ||||
-rw-r--r-- | src/core/dhcp/tests/test-dhcp-dhclient.c | 2 |
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), |