mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
[DlgCreateGame] Heap-allocate create game dialog to prevent crash on parent deletion (#7777)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / vcpkg baseline (push) Waiting to run
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 sanitize (push) Blocked by required conditions
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 27 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / vcpkg baseline (push) Waiting to run
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 sanitize (push) Blocked by required conditions
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 27 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
* [DlgCreateGame] Heap-allocate create game dialog to prevent crash on parent deletion * [Tests] Run the short-write cases without forking a death test The three cases that force a write failure - CardDatabaseTest.Xml4ShortWriteKeepsInstalledFile, OracleDatabaseWriter.ShortWriteKeepsPreviouslyInstalledDatabase and SpoilerFileTest.ShortWriteLeavesExistingFileIntact - all forked a child, lowered RLIMIT_FSIZE and ignored SIGXFSZ. That child is killed by SIGSEGV on the macOS runners, so all three have been red on every macOS leg of master since they landed, while the same cases pass on Linux. Cap the soft limit in the test process instead: ctest already runs one case per process, and the guard restores the limit and the SIGXFSZ handler, so a whole binary keeps working. Same real EFBIG failure, no fork, and macOS keeps its coverage of the writers. * [CI] Derive DEBUG_TEST and RUN_TESTS in the nightly job The shared steps gate on both, but build-linux-nightly never set them, so its coverage leg skipped "Build debug and test" and then failed collecting a report from an empty build/ directory on every nightly and tag run. continue-on-error kept the run green, so the coverage artifact silently never existed. Derive both exactly as the pull request job does. --------- Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com> Co-authored-by: Lukas Brübach <44814898+BruebachL@users.noreply.github.com>
This commit is contained in:
parent
df74917cb0
commit
64c7809332
7 changed files with 132 additions and 71 deletions
83
tests/support/scoped_file_size_limit.h
Normal file
83
tests/support/scoped_file_size_limit.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#ifndef COCKATRICE_TEST_SCOPED_FILE_SIZE_LIMIT_H
|
||||
#define COCKATRICE_TEST_SCOPED_FILE_SIZE_LIMIT_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
|
||||
#include <algorithm>
|
||||
#include <csignal>
|
||||
#include <sys/resource.h>
|
||||
|
||||
namespace test_support
|
||||
{
|
||||
/**
|
||||
* @brief Caps how large a single file may grow, so a writer's short-write path is reachable.
|
||||
*
|
||||
* Lowering RLIMIT_FSIZE makes the next write past the cap fail with EFBIG instead of
|
||||
* filling a filesystem, which is the only way to fail an install step mid-write without
|
||||
* depending on free disk space or file ownership. Only the soft limit is lowered, so the
|
||||
* destructor can hand the process back exactly as it found it: ctest runs one case per
|
||||
* process, but a whole test binary must not carry the cap into its neighbours.
|
||||
*
|
||||
* Do not use this inside a gtest death test. A forked child under RLIMIT_FSIZE is killed
|
||||
* by SIGSEGV on the macOS runners, while the same case passes on Linux, so the fork is
|
||||
* what breaks - not the writer. The guard alone isolates the failure just as well.
|
||||
*/
|
||||
class ScopedFileSizeLimit
|
||||
{
|
||||
public:
|
||||
explicit ScopedFileSizeLimit(rlim_t maxBytes)
|
||||
{
|
||||
if (getrlimit(RLIMIT_FSIZE, &previousLimit) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct sigaction ignore = {};
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset(&ignore.sa_mask);
|
||||
if (sigaction(SIGXFSZ, &ignore, &previousAction) != 0) {
|
||||
return;
|
||||
}
|
||||
actionSaved = true;
|
||||
|
||||
struct rlimit capped = previousLimit;
|
||||
capped.rlim_cur = std::min(maxBytes, previousLimit.rlim_max);
|
||||
if (setrlimit(RLIMIT_FSIZE, &capped) != 0) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
}
|
||||
|
||||
~ScopedFileSizeLimit()
|
||||
{
|
||||
if (active) {
|
||||
setrlimit(RLIMIT_FSIZE, &previousLimit);
|
||||
}
|
||||
if (actionSaved) {
|
||||
sigaction(SIGXFSZ, &previousAction, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
ScopedFileSizeLimit(const ScopedFileSizeLimit &) = delete;
|
||||
ScopedFileSizeLimit &operator=(const ScopedFileSizeLimit &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Whether the cap is in force; a test that needs the failure must assert this.
|
||||
*/
|
||||
[[nodiscard]] bool isValid() const
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
private:
|
||||
bool active = false;
|
||||
bool actionSaved = false;
|
||||
struct rlimit previousLimit = {};
|
||||
struct sigaction previousAction = {};
|
||||
};
|
||||
} // namespace test_support
|
||||
|
||||
#endif // Q_OS_UNIX
|
||||
|
||||
#endif // COCKATRICE_TEST_SCOPED_FILE_SIZE_LIMIT_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue