mirror of
https://github.com/systemd/systemd
synced 2026-03-18 19:14:46 +01:00
Compare commits
No commits in common. "fd8d4026d4e7b4664571e923166693642794b505" and "f056560da73ac4573d0af2f7f0ec40497c1de855" have entirely different histories.
fd8d4026d4
...
f056560da7
4
NEWS
4
NEWS
@ -7,10 +7,6 @@ CHANGES WITH 260 in spe:
|
|||||||
* Meson options '-Dintegration-tests=' and '-Dcryptolib=' (deprecated
|
* Meson options '-Dintegration-tests=' and '-Dcryptolib=' (deprecated
|
||||||
in v258) have been removed.
|
in v258) have been removed.
|
||||||
|
|
||||||
* Support for libidn has been removed. IDN functionality now requires
|
|
||||||
libidn2. The corresponding meson option '-Dlibidn=' is deprecated
|
|
||||||
too and will be dropped in a future release.
|
|
||||||
|
|
||||||
CHANGES WITH 259:
|
CHANGES WITH 259:
|
||||||
|
|
||||||
Announcements of Future Feature Removals and Incompatible Changes:
|
Announcements of Future Feature Removals and Incompatible Changes:
|
||||||
|
|||||||
2
README
2
README
@ -240,7 +240,7 @@ REQUIREMENTS:
|
|||||||
libqrencode >= 3 (optional)
|
libqrencode >= 3 (optional)
|
||||||
libmicrohttpd >= 0.9.33 (optional)
|
libmicrohttpd >= 0.9.33 (optional)
|
||||||
libcurl >= 7.32.0 (optional)
|
libcurl >= 7.32.0 (optional)
|
||||||
libidn2 (optional)
|
libidn2 or libidn (optional)
|
||||||
gnutls >= 3.1.4 (optional)
|
gnutls >= 3.1.4 (optional)
|
||||||
openssl >= 3.0.0 (optional, required to support DNS-over-TLS)
|
openssl >= 3.0.0 (optional, required to support DNS-over-TLS)
|
||||||
p11-kit >= 0.23.3 (optional)
|
p11-kit >= 0.23.3 (optional)
|
||||||
|
|||||||
2
TODO
2
TODO
@ -563,6 +563,8 @@ Features:
|
|||||||
|
|
||||||
* port copy.c over to use LabelOps for all labelling.
|
* port copy.c over to use LabelOps for all labelling.
|
||||||
|
|
||||||
|
* get rid of compat with libidn.so.11 (retain only for libidn.so.12)
|
||||||
|
|
||||||
* get rid of compat with libbpf.so.0 (retainly only for libbpf.so.1)
|
* get rid of compat with libbpf.so.0 (retainly only for libbpf.so.1)
|
||||||
|
|
||||||
* define a generic "report" varlink interface, which services can implement to
|
* define a generic "report" varlink interface, which services can implement to
|
||||||
|
|||||||
17
meson.build
17
meson.build
@ -1290,10 +1290,18 @@ libcurl = dependency('libcurl',
|
|||||||
conf.set10('HAVE_LIBCURL', libcurl.found())
|
conf.set10('HAVE_LIBCURL', libcurl.found())
|
||||||
conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
|
conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
|
||||||
|
|
||||||
libidn2 = dependency('libidn2',
|
feature = get_option('libidn2').disable_auto_if(get_option('libidn').enabled())
|
||||||
required : get_option('libidn2'))
|
libidn = dependency('libidn2',
|
||||||
libidn2_cflags = libidn2.partial_dependency(includes: true, compile_args: true)
|
required : feature)
|
||||||
conf.set10('HAVE_LIBIDN2', libidn2.found())
|
have = libidn.found()
|
||||||
|
if not have
|
||||||
|
# libidn is used for both libidn and libidn2 objects
|
||||||
|
libidn = dependency('libidn',
|
||||||
|
required : get_option('libidn'))
|
||||||
|
endif
|
||||||
|
libidn_cflags = libidn.partial_dependency(includes: true, compile_args: true)
|
||||||
|
conf.set10('HAVE_LIBIDN', not have and libidn.found())
|
||||||
|
conf.set10('HAVE_LIBIDN2', have)
|
||||||
|
|
||||||
libqrencode = dependency('libqrencode',
|
libqrencode = dependency('libqrencode',
|
||||||
version : '>= 3',
|
version : '>= 3',
|
||||||
@ -3110,6 +3118,7 @@ foreach tuple : [
|
|||||||
['libcurl'],
|
['libcurl'],
|
||||||
['libfdisk'],
|
['libfdisk'],
|
||||||
['libfido2'],
|
['libfido2'],
|
||||||
|
['libidn'],
|
||||||
['libidn2'],
|
['libidn2'],
|
||||||
['microhttpd'],
|
['microhttpd'],
|
||||||
['openssl'],
|
['openssl'],
|
||||||
|
|||||||
@ -438,7 +438,7 @@ option('idn', type : 'boolean',
|
|||||||
description : 'use IDN when printing hostnames')
|
description : 'use IDN when printing hostnames')
|
||||||
option('libidn2', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
|
option('libidn2', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
|
||||||
description : 'libidn2 support')
|
description : 'libidn2 support')
|
||||||
option('libidn', type : 'feature', deprecated : true,
|
option('libidn', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
|
||||||
description : 'libidn support')
|
description : 'libidn support')
|
||||||
option('libiptc', type : 'feature', deprecated : true,
|
option('libiptc', type : 'feature', deprecated : true,
|
||||||
description : 'libiptc support')
|
description : 'libiptc support')
|
||||||
|
|||||||
@ -120,6 +120,12 @@ const char* const systemd_features =
|
|||||||
" -IDN2"
|
" -IDN2"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN
|
||||||
|
" +IDN"
|
||||||
|
#else
|
||||||
|
" -IDN"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_KMOD
|
#if HAVE_KMOD
|
||||||
" +KMOD"
|
" +KMOD"
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -355,18 +355,20 @@ int decompress_blob_xz(
|
|||||||
assert(dst_size);
|
assert(dst_size);
|
||||||
|
|
||||||
#if HAVE_XZ
|
#if HAVE_XZ
|
||||||
|
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
size_t space;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_lzma();
|
r = dlopen_lzma();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||||
lzma_ret ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
|
||||||
if (ret != LZMA_OK)
|
if (ret != LZMA_OK)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
size_t space = MIN(src_size * 2, dst_max ?: SIZE_MAX);
|
space = MIN(src_size * 2, dst_max ?: SIZE_MAX);
|
||||||
if (!greedy_realloc(dst, space, 1))
|
if (!greedy_realloc(dst, space, 1))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -548,21 +550,23 @@ int decompress_startswith_xz(
|
|||||||
assert(prefix);
|
assert(prefix);
|
||||||
|
|
||||||
#if HAVE_XZ
|
#if HAVE_XZ
|
||||||
|
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
size_t allocated;
|
||||||
|
lzma_ret ret;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_lzma();
|
r = dlopen_lzma();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||||
lzma_ret ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
|
||||||
if (ret != LZMA_OK)
|
if (ret != LZMA_OK)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
if (!(greedy_realloc(buffer, ALIGN_8(prefix_len + 1), 1)))
|
if (!(greedy_realloc(buffer, ALIGN_8(prefix_len + 1), 1)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
size_t allocated = MALLOC_SIZEOF_SAFE(*buffer);
|
allocated = MALLOC_SIZEOF_SAFE(*buffer);
|
||||||
|
|
||||||
s.next_in = src;
|
s.next_in = src;
|
||||||
s.avail_in = src_size;
|
s.avail_in = src_size;
|
||||||
@ -768,21 +772,22 @@ int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncom
|
|||||||
assert(fdt >= 0);
|
assert(fdt >= 0);
|
||||||
|
|
||||||
#if HAVE_XZ
|
#if HAVE_XZ
|
||||||
|
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
uint8_t buf[BUFSIZ], out[BUFSIZ];
|
||||||
|
lzma_action action = LZMA_RUN;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_lzma();
|
r = dlopen_lzma();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
ret = sym_lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64);
|
||||||
lzma_ret ret = sym_lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64);
|
|
||||||
if (ret != LZMA_OK)
|
if (ret != LZMA_OK)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Failed to initialize XZ encoder: code %u",
|
"Failed to initialize XZ encoder: code %u",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
uint8_t buf[BUFSIZ], out[BUFSIZ];
|
|
||||||
lzma_action action = LZMA_RUN;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (s.avail_in == 0 && action == LZMA_RUN) {
|
if (s.avail_in == 0 && action == LZMA_RUN) {
|
||||||
size_t m = sizeof(buf);
|
size_t m = sizeof(buf);
|
||||||
@ -947,21 +952,23 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
|
|||||||
assert(fdt >= 0);
|
assert(fdt >= 0);
|
||||||
|
|
||||||
#if HAVE_XZ
|
#if HAVE_XZ
|
||||||
|
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
|
||||||
|
uint8_t buf[BUFSIZ], out[BUFSIZ];
|
||||||
|
lzma_action action = LZMA_RUN;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_lzma();
|
r = dlopen_lzma();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_cleanup_(lzma_end_wrapper) lzma_stream s = LZMA_STREAM_INIT;
|
ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||||
lzma_ret ret = sym_lzma_stream_decoder(&s, UINT64_MAX, 0);
|
|
||||||
if (ret != LZMA_OK)
|
if (ret != LZMA_OK)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOMEM),
|
return log_debug_errno(SYNTHETIC_ERRNO(ENOMEM),
|
||||||
"Failed to initialize XZ decoder: code %u",
|
"Failed to initialize XZ decoder: code %u",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
uint8_t buf[BUFSIZ], out[BUFSIZ];
|
|
||||||
lzma_action action = LZMA_RUN;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (s.avail_in == 0 && action == LZMA_RUN) {
|
if (s.avail_in == 0 && action == LZMA_RUN) {
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|||||||
@ -68,7 +68,6 @@ endif
|
|||||||
|
|
||||||
resolve_common_template = {
|
resolve_common_template = {
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libidn2_cflags,
|
|
||||||
libopenssl,
|
libopenssl,
|
||||||
libm,
|
libm,
|
||||||
threads,
|
threads,
|
||||||
@ -92,6 +91,9 @@ executables += [
|
|||||||
'resolvconf-compat.c',
|
'resolvconf-compat.c',
|
||||||
'resolvectl.c',
|
'resolvectl.c',
|
||||||
),
|
),
|
||||||
|
'dependencies' : resolve_common_template['dependencies'] + [
|
||||||
|
libidn,
|
||||||
|
],
|
||||||
'objects' : ['systemd-resolved'],
|
'objects' : ['systemd-resolved'],
|
||||||
},
|
},
|
||||||
resolve_test_template + {
|
resolve_test_template + {
|
||||||
|
|||||||
@ -12,6 +12,11 @@
|
|||||||
|
|
||||||
int resolve_system_hostname(char **full_hostname, char **first_label) {
|
int resolve_system_hostname(char **full_hostname, char **first_label) {
|
||||||
_cleanup_free_ char *h = NULL, *n = NULL;
|
_cleanup_free_ char *h = NULL, *n = NULL;
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
|
_cleanup_free_ char *utf8 = NULL;
|
||||||
|
#elif HAVE_LIBIDN
|
||||||
|
int k;
|
||||||
|
#endif
|
||||||
char label[DNS_LABEL_MAX+1];
|
char label[DNS_LABEL_MAX+1];
|
||||||
const char *p, *decoded;
|
const char *p, *decoded;
|
||||||
int r;
|
int r;
|
||||||
@ -33,10 +38,15 @@ int resolve_system_hostname(char **full_hostname, char **first_label) {
|
|||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Couldn't find a single label in hostname.");
|
"Couldn't find a single label in hostname.");
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
|
r = dlopen_idn();
|
||||||
|
if (r < 0) {
|
||||||
|
log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m");
|
||||||
|
decoded = label; /* no decoding */
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN2
|
||||||
_cleanup_free_ char *utf8 = NULL;
|
|
||||||
|
|
||||||
if (dlopen_idn() >= 0) {
|
|
||||||
r = sym_idn2_to_unicode_8z8z(label, &utf8, 0);
|
r = sym_idn2_to_unicode_8z8z(label, &utf8, 0);
|
||||||
if (r != IDN2_OK)
|
if (r != IDN2_OK)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
|
return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
|
||||||
@ -45,9 +55,21 @@ int resolve_system_hostname(char **full_hostname, char **first_label) {
|
|||||||
|
|
||||||
r = strlen(utf8);
|
r = strlen(utf8);
|
||||||
decoded = utf8;
|
decoded = utf8;
|
||||||
} else
|
#elif HAVE_LIBIDN
|
||||||
#endif
|
k = dns_label_undo_idna(label, r, label, sizeof label);
|
||||||
|
if (k < 0)
|
||||||
|
return log_debug_errno(k, "Failed to undo IDNA: %m");
|
||||||
|
if (k > 0)
|
||||||
|
r = k;
|
||||||
|
|
||||||
|
if (!utf8_is_valid(label))
|
||||||
|
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"System hostname is not UTF-8 clean.");
|
||||||
|
decoded = label;
|
||||||
|
#else
|
||||||
decoded = label; /* no decoding */
|
decoded = label; /* no decoding */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
r = dns_label_escape_new(decoded, r, &n);
|
r = dns_label_escape_new(decoded, r, &n);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@ -85,7 +85,7 @@ TEST(dns_query_new_multi_question_different_domain) {
|
|||||||
ASSERT_NULL(query);
|
ASSERT_NULL(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
TEST(dns_query_new_same_utf8_and_idna) {
|
TEST(dns_query_new_same_utf8_and_idna) {
|
||||||
Manager manager = {};
|
Manager manager = {};
|
||||||
_cleanup_(dns_question_unrefp) DnsQuestion *q_utf8 = NULL, *q_idna = NULL;
|
_cleanup_(dns_question_unrefp) DnsQuestion *q_utf8 = NULL, *q_idna = NULL;
|
||||||
@ -434,7 +434,7 @@ TEST(dns_query_process_cname_one_success_match_dname) {
|
|||||||
dns_resource_key_unref(key);
|
dns_resource_key_unref(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
TEST(dns_query_process_cname_one_success_match_dname_utf8_same) {
|
TEST(dns_query_process_cname_one_success_match_dname_utf8_same) {
|
||||||
Manager manager = {};
|
Manager manager = {};
|
||||||
_cleanup_(dns_question_unrefp) DnsQuestion *q_utf8 = NULL, *q_idna = NULL;
|
_cleanup_(dns_question_unrefp) DnsQuestion *q_utf8 = NULL, *q_idna = NULL;
|
||||||
|
|||||||
@ -62,7 +62,7 @@ TEST(dns_question_new_address) {
|
|||||||
ASSERT_OK_POSITIVE(dns_question_contains_key(question, key6));
|
ASSERT_OK_POSITIVE(dns_question_contains_key(question, key6));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
TEST(dns_question_new_address_convert_idna) {
|
TEST(dns_question_new_address_convert_idna) {
|
||||||
_cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
|
_cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
|
||||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
|
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
|
||||||
@ -162,7 +162,7 @@ TEST(dns_question_new_service) {
|
|||||||
question = dns_question_unref(question);
|
question = dns_question_unref(question);
|
||||||
key = dns_resource_key_unref(key);
|
key = dns_resource_key_unref(key);
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
/* convert idna with type */
|
/* convert idna with type */
|
||||||
ASSERT_OK(dns_question_new_service(
|
ASSERT_OK(dns_question_new_service(
|
||||||
&question,
|
&question,
|
||||||
|
|||||||
@ -195,7 +195,7 @@ int main(int argc, char* argv[]) {
|
|||||||
test_hostname_lookup(bus, "poettering.de", AF_INET, NULL);
|
test_hostname_lookup(bus, "poettering.de", AF_INET, NULL);
|
||||||
test_hostname_lookup(bus, "poettering.de", AF_INET6, NULL);
|
test_hostname_lookup(bus, "poettering.de", AF_INET6, NULL);
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN2 || HAVE_LIBIDN
|
||||||
/* Unsigned A with IDNA conversion necessary */
|
/* Unsigned A with IDNA conversion necessary */
|
||||||
test_hostname_lookup(bus, "pöttering.de", AF_UNSPEC, NULL);
|
test_hostname_lookup(bus, "pöttering.de", AF_UNSPEC, NULL);
|
||||||
test_hostname_lookup(bus, "pöttering.de", AF_INET, NULL);
|
test_hostname_lookup(bus, "pöttering.de", AF_INET, NULL);
|
||||||
|
|||||||
@ -301,6 +301,111 @@ int dns_name_parent(const char **name) {
|
|||||||
return dns_label_unescape(name, NULL, DNS_LABEL_MAX, 0);
|
return dns_label_unescape(name, NULL, DNS_LABEL_MAX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN
|
||||||
|
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
|
||||||
|
_cleanup_free_ uint32_t *input = NULL;
|
||||||
|
size_t input_size, l;
|
||||||
|
bool contains_8_bit = false;
|
||||||
|
char buffer[DNS_LABEL_MAX+1];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(encoded);
|
||||||
|
assert(decoded);
|
||||||
|
|
||||||
|
/* Converts a U-label into an A-label */
|
||||||
|
|
||||||
|
r = dlopen_idn();
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (encoded_size <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (const char *p = encoded; p < encoded + encoded_size; p++)
|
||||||
|
if ((uint8_t) *p > 127)
|
||||||
|
contains_8_bit = true;
|
||||||
|
|
||||||
|
if (!contains_8_bit) {
|
||||||
|
if (encoded_size > DNS_LABEL_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = sym_stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
|
||||||
|
if (!input)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (sym_idna_to_ascii_4i(input, input_size, buffer, 0) != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
l = strlen(buffer);
|
||||||
|
|
||||||
|
/* Verify that the result is not longer than one DNS label. */
|
||||||
|
if (l <= 0 || l > DNS_LABEL_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
if (l > decoded_max)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
memcpy(decoded, buffer, l);
|
||||||
|
|
||||||
|
/* If there's room, append a trailing NUL byte, but only then */
|
||||||
|
if (decoded_max > l)
|
||||||
|
decoded[l] = 0;
|
||||||
|
|
||||||
|
return (int) l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
|
||||||
|
size_t input_size, output_size;
|
||||||
|
_cleanup_free_ uint32_t *input = NULL;
|
||||||
|
_cleanup_free_ char *result = NULL;
|
||||||
|
uint32_t *output = NULL;
|
||||||
|
size_t w;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* To be invoked after unescaping. Converts an A-label into a U-label. */
|
||||||
|
|
||||||
|
assert(encoded);
|
||||||
|
assert(decoded);
|
||||||
|
|
||||||
|
r = dlopen_idn();
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (encoded_size <= 0 || encoded_size > DNS_LABEL_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!memory_startswith(encoded, encoded_size, IDNA_ACE_PREFIX))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
input = sym_stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
|
||||||
|
if (!input)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
output_size = input_size;
|
||||||
|
output = newa(uint32_t, output_size);
|
||||||
|
|
||||||
|
sym_idna_to_unicode_44i(input, input_size, output, &output_size, 0);
|
||||||
|
|
||||||
|
result = sym_stringprep_ucs4_to_utf8(output, output_size, NULL, &w);
|
||||||
|
if (!result)
|
||||||
|
return -ENOMEM;
|
||||||
|
if (w <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
if (w > decoded_max)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
memcpy(decoded, result, w);
|
||||||
|
|
||||||
|
/* Append trailing NUL byte if there's space, but only then. */
|
||||||
|
if (decoded_max > w)
|
||||||
|
decoded[w] = 0;
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret) {
|
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret) {
|
||||||
_cleanup_free_ char *result = NULL;
|
_cleanup_free_ char *result = NULL;
|
||||||
size_t n_result = 0, n_unescaped = 0;
|
size_t n_result = 0, n_unescaped = 0;
|
||||||
@ -1264,7 +1369,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||||||
|
|
||||||
/* Return negative on error, 0 if not implemented, positive on success. */
|
/* Return negative on error, 0 if not implemented, positive on success. */
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN2 || HAVE_LIBIDN2
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_idn();
|
r = dlopen_idn();
|
||||||
@ -1274,7 +1379,9 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||||||
}
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
_cleanup_free_ char *t = NULL;
|
_cleanup_free_ char *t = NULL;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
@ -1322,6 +1429,55 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
#elif HAVE_LIBIDN
|
||||||
|
_cleanup_free_ char *buf = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
bool first = true;
|
||||||
|
int r, q;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char label[DNS_LABEL_MAX+1];
|
||||||
|
|
||||||
|
r = dns_label_unescape(&name, label, sizeof label, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
q = dns_label_apply_idna(label, r, label, sizeof label);
|
||||||
|
if (q < 0)
|
||||||
|
return q;
|
||||||
|
if (q > 0)
|
||||||
|
r = q;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(buf, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
buf[n++] = '.';
|
||||||
|
|
||||||
|
n += r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > DNS_HOSTNAME_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(buf, n + 1))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
buf[n] = 0;
|
||||||
|
*ret = TAKE_PTR(buf);
|
||||||
|
|
||||||
|
return 1;
|
||||||
#else
|
#else
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -16,6 +16,11 @@ int dns_label_escape_new(const char *p, size_t l, char **ret);
|
|||||||
|
|
||||||
int dns_name_parent(const char **name);
|
int dns_name_parent(const char **name);
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN
|
||||||
|
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
|
||||||
|
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
|
||||||
|
#endif
|
||||||
|
|
||||||
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret);
|
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret);
|
||||||
|
|
||||||
static inline int dns_name_normalize(const char *s, DNSLabelFlags flags, char **ret) {
|
static inline int dns_name_normalize(const char *s, DNSLabelFlags flags, char **ret) {
|
||||||
|
|||||||
@ -298,12 +298,6 @@ static int run_editor_child(const EditFileContext *context) {
|
|||||||
|
|
||||||
execvp(args[0], (char* const*) args);
|
execvp(args[0], (char* const*) args);
|
||||||
|
|
||||||
if (errno == ENOTDIR) {
|
|
||||||
log_debug_errno(errno,
|
|
||||||
"Failed to execute '%s': a path component is not a directory, skipping...",
|
|
||||||
name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* We do not fail if the editor doesn't exist because we want to try each one of them
|
/* We do not fail if the editor doesn't exist because we want to try each one of them
|
||||||
* before failing. */
|
* before failing. */
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
|
# include <idn2.h>
|
||||||
|
#elif HAVE_LIBIDN
|
||||||
|
# include <idna.h>
|
||||||
|
# include <stringprep.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "dlfcn-util.h"
|
||||||
#include "idn-util.h"
|
#include "idn-util.h"
|
||||||
#include "log.h" /* IWYU pragma: keep */
|
#include "log.h" /* IWYU pragma: keep */
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN || HAVE_LIBIDN2
|
||||||
static void* idn_dl = NULL;
|
static void* idn_dl = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
DLSYM_PROTOTYPE(idn2_lookup_u8) = NULL;
|
DLSYM_PROTOTYPE(idn2_lookup_u8) = NULL;
|
||||||
const char *(*sym_idn2_strerror)(int rc) _const_ = NULL;
|
const char *(*sym_idn2_strerror)(int rc) _const_ = NULL;
|
||||||
DLSYM_PROTOTYPE(idn2_to_unicode_8z8z) = NULL;
|
DLSYM_PROTOTYPE(idn2_to_unicode_8z8z) = NULL;
|
||||||
@ -21,3 +32,56 @@ int dlopen_idn(void) {
|
|||||||
DLSYM_ARG(idn2_strerror),
|
DLSYM_ARG(idn2_strerror),
|
||||||
DLSYM_ARG(idn2_to_unicode_8z8z));
|
DLSYM_ARG(idn2_to_unicode_8z8z));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN
|
||||||
|
DLSYM_PROTOTYPE(idna_to_ascii_4i) = NULL;
|
||||||
|
DLSYM_PROTOTYPE(idna_to_unicode_44i) = NULL;
|
||||||
|
DLSYM_PROTOTYPE(stringprep_ucs4_to_utf8) = NULL;
|
||||||
|
DLSYM_PROTOTYPE(stringprep_utf8_to_ucs4) = NULL;
|
||||||
|
|
||||||
|
int dlopen_idn(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
ELF_NOTE_DLOPEN("idn",
|
||||||
|
"Support for internationalized domain names",
|
||||||
|
ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||||
|
"libidn.so.12", "libidn.so.11");
|
||||||
|
|
||||||
|
if (idn_dl)
|
||||||
|
return 0; /* Already loaded */
|
||||||
|
|
||||||
|
r = check_dlopen_blocked("libidn.so.12");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
_cleanup_(dlclosep) void *dl = NULL;
|
||||||
|
r = dlopen_safe("libidn.so.12", &dl, /* reterr_dlerror= */ NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
/* libidn broke ABI in 1.34, but not in a way we care about (a new field got added to an
|
||||||
|
* open-coded struct we do not use), hence support both versions. */
|
||||||
|
const char *dle = NULL;
|
||||||
|
r = dlopen_safe("libidn.so.11", &dl, &dle);
|
||||||
|
if (r < 0) {
|
||||||
|
log_debug_errno(r, "libidn support is not available: %s", dle ?: STRERROR(r));
|
||||||
|
return -EOPNOTSUPP; /* turn into recognizable error */
|
||||||
|
}
|
||||||
|
log_debug("Loaded 'libidn.so.11' via dlopen()");
|
||||||
|
} else
|
||||||
|
log_debug("Loaded 'libidn.so.12' via dlopen()");
|
||||||
|
|
||||||
|
r = dlsym_many_or_warn(
|
||||||
|
dl,
|
||||||
|
LOG_DEBUG,
|
||||||
|
DLSYM_ARG(idna_to_ascii_4i),
|
||||||
|
DLSYM_ARG(idna_to_unicode_44i),
|
||||||
|
DLSYM_ARG(stringprep_ucs4_to_utf8),
|
||||||
|
DLSYM_ARG(stringprep_utf8_to_ucs4));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
idn_dl = TAKE_PTR(dl);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@ -1,20 +1,34 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
|
# include <idn2.h>
|
||||||
|
#elif HAVE_LIBIDN
|
||||||
|
# include <idna.h>
|
||||||
|
# include <stringprep.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "shared-forward.h"
|
#include "shared-forward.h"
|
||||||
|
|
||||||
#if HAVE_LIBIDN2
|
#if HAVE_LIBIDN2 || HAVE_LIBIDN
|
||||||
#include <idn2.h>
|
|
||||||
|
|
||||||
#include "dlfcn-util.h"
|
#include "dlfcn-util.h"
|
||||||
|
|
||||||
extern DLSYM_PROTOTYPE(idn2_lookup_u8);
|
|
||||||
extern const char *(*sym_idn2_strerror)(int rc) _const_;
|
|
||||||
extern DLSYM_PROTOTYPE(idn2_to_unicode_8z8z);
|
|
||||||
|
|
||||||
int dlopen_idn(void);
|
int dlopen_idn(void);
|
||||||
#else
|
#else
|
||||||
static inline int dlopen_idn(void) {
|
static inline int dlopen_idn(void) {
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2
|
||||||
|
extern DLSYM_PROTOTYPE(idn2_lookup_u8);
|
||||||
|
extern const char *(*sym_idn2_strerror)(int rc) _const_;
|
||||||
|
extern DLSYM_PROTOTYPE(idn2_to_unicode_8z8z);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN
|
||||||
|
extern DLSYM_PROTOTYPE(idna_to_ascii_4i);
|
||||||
|
extern DLSYM_PROTOTYPE(idna_to_unicode_44i);
|
||||||
|
extern DLSYM_PROTOTYPE(stringprep_ucs4_to_utf8);
|
||||||
|
extern DLSYM_PROTOTYPE(stringprep_utf8_to_ucs4);
|
||||||
|
#endif
|
||||||
|
|||||||
@ -92,6 +92,7 @@ shared_sources = files(
|
|||||||
'hostname-setup.c',
|
'hostname-setup.c',
|
||||||
'hwdb-util.c',
|
'hwdb-util.c',
|
||||||
'id128-print.c',
|
'id128-print.c',
|
||||||
|
'idn-util.c',
|
||||||
'ima-util.c',
|
'ima-util.c',
|
||||||
'image-policy.c',
|
'image-policy.c',
|
||||||
'import-util.c',
|
'import-util.c',
|
||||||
@ -270,10 +271,6 @@ if conf.get('HAVE_LIBMOUNT') == 1
|
|||||||
shared_sources += files('libmount-util.c')
|
shared_sources += files('libmount-util.c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if conf.get('HAVE_LIBIDN2') == 1
|
|
||||||
shared_sources += files('idn-util.c')
|
|
||||||
endif
|
|
||||||
|
|
||||||
generate_ip_protocol_list = files('generate-ip-protocol-list.sh')
|
generate_ip_protocol_list = files('generate-ip-protocol-list.sh')
|
||||||
ip_protocol_list_txt = custom_target(
|
ip_protocol_list_txt = custom_target(
|
||||||
input : [generate_ip_protocol_list, ipproto_sources],
|
input : [generate_ip_protocol_list, ipproto_sources],
|
||||||
@ -377,7 +374,7 @@ libshared_deps = [threads,
|
|||||||
libelf_cflags,
|
libelf_cflags,
|
||||||
libfido2_cflags,
|
libfido2_cflags,
|
||||||
libgcrypt_cflags,
|
libgcrypt_cflags,
|
||||||
libidn2_cflags,
|
libidn_cflags,
|
||||||
libkmod_cflags,
|
libkmod_cflags,
|
||||||
libmount_cflags,
|
libmount_cflags,
|
||||||
libopenssl,
|
libopenssl,
|
||||||
|
|||||||
@ -47,7 +47,7 @@ static int run(int argc, char **argv) {
|
|||||||
ASSERT_DLOPEN(dlopen_dw, HAVE_ELFUTILS);
|
ASSERT_DLOPEN(dlopen_dw, HAVE_ELFUTILS);
|
||||||
ASSERT_DLOPEN(dlopen_elf, HAVE_ELFUTILS);
|
ASSERT_DLOPEN(dlopen_elf, HAVE_ELFUTILS);
|
||||||
ASSERT_DLOPEN(dlopen_gcrypt, HAVE_GCRYPT);
|
ASSERT_DLOPEN(dlopen_gcrypt, HAVE_GCRYPT);
|
||||||
ASSERT_DLOPEN(dlopen_idn, HAVE_LIBIDN2);
|
ASSERT_DLOPEN(dlopen_idn, HAVE_LIBIDN2 || HAVE_LIBIDN);
|
||||||
ASSERT_DLOPEN(dlopen_libacl, HAVE_ACL);
|
ASSERT_DLOPEN(dlopen_libacl, HAVE_ACL);
|
||||||
ASSERT_DLOPEN(dlopen_libapparmor, HAVE_APPARMOR);
|
ASSERT_DLOPEN(dlopen_libapparmor, HAVE_APPARMOR);
|
||||||
ASSERT_DLOPEN(dlopen_libarchive, HAVE_LIBARCHIVE);
|
ASSERT_DLOPEN(dlopen_libarchive, HAVE_LIBARCHIVE);
|
||||||
|
|||||||
@ -788,7 +788,7 @@ static void test_dns_name_apply_idna_one(const char *s, int expected, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(dns_name_apply_idna) {
|
TEST(dns_name_apply_idna) {
|
||||||
const int ret = HAVE_LIBIDN2;
|
const int ret = HAVE_LIBIDN2 | HAVE_LIBIDN;
|
||||||
|
|
||||||
/* IDNA2008 forbids names with hyphens in third and fourth positions
|
/* IDNA2008 forbids names with hyphens in third and fourth positions
|
||||||
* (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
|
* (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
|
||||||
@ -798,6 +798,7 @@ TEST(dns_name_apply_idna) {
|
|||||||
* labels. If registrars follow IDNA2008 we'll just be performing a
|
* labels. If registrars follow IDNA2008 we'll just be performing a
|
||||||
* useless lookup.
|
* useless lookup.
|
||||||
*/
|
*/
|
||||||
|
const int ret2 = HAVE_LIBIDN;
|
||||||
|
|
||||||
test_dns_name_apply_idna_one("", ret, "");
|
test_dns_name_apply_idna_one("", ret, "");
|
||||||
test_dns_name_apply_idna_one("foo", ret, "foo");
|
test_dns_name_apply_idna_one("foo", ret, "foo");
|
||||||
@ -810,13 +811,14 @@ TEST(dns_name_apply_idna) {
|
|||||||
test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
|
test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
|
||||||
test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
|
test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
|
||||||
|
|
||||||
test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", 0,
|
test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2,
|
||||||
"_443._tcp.fedoraproject.org");
|
"_443._tcp.fedoraproject.org");
|
||||||
test_dns_name_apply_idna_one("_443", 0, "_443");
|
test_dns_name_apply_idna_one("_443", ret2, "_443");
|
||||||
test_dns_name_apply_idna_one("gateway", 0, "gateway");
|
test_dns_name_apply_idna_one("gateway", ret, "gateway");
|
||||||
test_dns_name_apply_idna_one("_gateway", 0, "_gateway");
|
test_dns_name_apply_idna_one("_gateway", ret2, "_gateway");
|
||||||
|
|
||||||
test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", 0, "");
|
test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
|
||||||
|
ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(dns_name_is_valid_or_address) {
|
TEST(dns_name_is_valid_or_address) {
|
||||||
|
|||||||
@ -433,13 +433,11 @@ static void test_format_timestamp_impl(usec_t x) {
|
|||||||
if (x_sec == y_sec && streq(xx, yy))
|
if (x_sec == y_sec && streq(xx, yy))
|
||||||
return; /* Yay! */
|
return; /* Yay! */
|
||||||
|
|
||||||
/* When the timezone is built with rearguard being enabled (e.g. old Ubuntu and RHEL), the timezone
|
/* When the timezone is built with rearguard being enabled (e.g. old Ubuntu and RHEL), the following
|
||||||
* Africa/Windhoek may provide time shifted 1 hour from the original. See
|
* timezone may provide time shifted 1 hour from the original. See
|
||||||
* https://github.com/systemd/systemd/issues/28472 and https://github.com/systemd/systemd/pull/35471.
|
* https://github.com/systemd/systemd/issues/28472 and https://github.com/systemd/systemd/pull/35471 */
|
||||||
* Also, the same may happen on MSK timezone (e.g. Europe/Volgograd or Europe/Kirov). */
|
|
||||||
bool ignore =
|
bool ignore =
|
||||||
(streq_ptr(getenv("TZ"), "Africa/Windhoek") ||
|
streq_ptr(getenv("TZ"), "Africa/Windhoek") &&
|
||||||
streq_ptr(get_tzname(/* dst= */ false), "MSK")) &&
|
|
||||||
(x_sec > y_sec ? x_sec - y_sec : y_sec - x_sec) == 3600;
|
(x_sec > y_sec ? x_sec - y_sec : y_sec - x_sec) == 3600;
|
||||||
|
|
||||||
log_full(ignore ? LOG_WARNING : LOG_ERR,
|
log_full(ignore ? LOG_WARNING : LOG_ERR,
|
||||||
@ -461,9 +459,6 @@ static void test_format_timestamp_loop(void) {
|
|||||||
test_format_timestamp_impl(1504938962980066);
|
test_format_timestamp_impl(1504938962980066);
|
||||||
test_format_timestamp_impl(1509482094632752);
|
test_format_timestamp_impl(1509482094632752);
|
||||||
|
|
||||||
/* With tzdata-2025c, the timestamp (randomly?) fails on MSK time zone (e.g. Europe/Volgograd). */
|
|
||||||
test_format_timestamp_impl(1414277092997572);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < TRIAL; i++) {
|
for (unsigned i = 0; i < TRIAL; i++) {
|
||||||
usec_t x;
|
usec_t x;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user