ci+fix: UCRT time functions on Windows; skip libsnappy on MinGW; NUL-terminated names in the mt test
- timeformat node: localtime_s/gmtime_s (reversed args, 64-bit time_t) on Windows — MinGW has no localtime_r/gmtime_r - the multithread suite test passed non-NUL-terminated property names (str::as_ptr) to the C property suite — UB that resolved to garbage lookups on the CI runner - libsnappy off on the MinGW FFmpeg build (only feeds the hap encoder; its pkg-config entry does not reach the static link)
This commit is contained in:
@@ -67,11 +67,18 @@ struct Tm {
|
||||
|
||||
// `localtime_r` / `gmtime_r` (C `time.h`). Declared locally instead of
|
||||
// pulling in a libc crate; both symbols live in the platform C library
|
||||
// that `std` already links.
|
||||
// that `std` already links. Windows (UCRT) has the `_s` variants with
|
||||
// reversed argument order and a 64-bit time_t.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
extern "C" {
|
||||
fn localtime_r(timep: *const c_long, result: *mut Tm) -> *mut Tm;
|
||||
fn gmtime_r(timep: *const c_long, result: *mut Tm) -> *mut Tm;
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
extern "C" {
|
||||
fn localtime_s(result: *mut Tm, timep: *const i64) -> i32;
|
||||
fn gmtime_s(result: *mut Tm, timep: *const i64) -> i32;
|
||||
}
|
||||
|
||||
/// Expand Qt date/time format tokens (`QDateTime::toString` syntax):
|
||||
/// the field tokens d/dd, M/MM, yy/yyyy, h/hh, H/HH, m/mm, s/ss, z/zz/zzz,
|
||||
@@ -287,6 +294,7 @@ impl NodeBehavior for TimeFormatNode {
|
||||
let ms = (ms_since_epoch % 1000) as i32;
|
||||
|
||||
let mut tm: Tm = unsafe { std::mem::zeroed() };
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
unsafe {
|
||||
if to_bool(&local_val) {
|
||||
localtime_r(&secs, &mut tm);
|
||||
@@ -294,6 +302,15 @@ impl NodeBehavior for TimeFormatNode {
|
||||
gmtime_r(&secs, &mut tm);
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe {
|
||||
let secs64 = secs as i64;
|
||||
if to_bool(&local_val) {
|
||||
localtime_s(&mut tm, &secs64);
|
||||
} else {
|
||||
gmtime_s(&mut tm, &secs64);
|
||||
}
|
||||
}
|
||||
|
||||
let output = format_date_time(&tm, ms, &to_text(&format_val));
|
||||
table.push(crate::value::ValueType::Text, NodeValue::Text(output), None);
|
||||
|
||||
@@ -743,14 +743,16 @@ fn multithread_suite_spawned_callbacks() {
|
||||
assert_eq!((s.multi_thread)(counter_worker, 8, raw as *mut c_void), OK);
|
||||
}
|
||||
for i in 0..8 {
|
||||
let name = Box::leak(format!("ctr{i}").into_boxed_str());
|
||||
// C 侧按 NUL 结尾读名字——必须经 cs() 包成 CString(裸
|
||||
// `str::as_ptr()` 不带 NUL,CStr::from_ptr 会读越界)。
|
||||
let name = cs(&format!("ctr{i}"));
|
||||
let mut v = 0;
|
||||
// 注意 `&*set`(Arc 负载)而非 `&set`(Arc 结构体)。
|
||||
// 注意传 `&*set`(Arc 负载)而非 `&set`(Arc 结构体)。
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
(ps.get_int)(
|
||||
&*set as *const _ as *mut c_void,
|
||||
name.as_ptr() as *const c_char,
|
||||
name.as_ptr(),
|
||||
0,
|
||||
&mut v
|
||||
),
|
||||
|
||||
@@ -139,12 +139,12 @@ if [ -d /opt/homebrew/lib/pkgconfig/openjpeg ]; then
|
||||
fi
|
||||
enable_if_pkg libopenjp2 libopenjpeg
|
||||
# openh264 is redundant for us (decode: FFmpeg's native h264; encode:
|
||||
# x264) and its MinGW package does not satisfy the static link — skip it
|
||||
# on Windows.
|
||||
# x264) and snappy only feeds the hap encoder; neither MinGW package
|
||||
# satisfies the static link — skip both on Windows.
|
||||
if [ -z "${MSYSTEM:-}" ]; then
|
||||
enable_if_pkg openh264 libopenh264
|
||||
enable_if_pkg snappy libsnappy
|
||||
fi
|
||||
enable_if_pkg snappy libsnappy
|
||||
enable_if_pkg wavpack libwavpack
|
||||
enable_if_pkg webp libwebp
|
||||
enable_if_pkg xvid libxvid
|
||||
|
||||
Reference in New Issue
Block a user