diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f2ac1baa..650a5ea52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ # Changelog +## Unreleased + +**Fixes**: + +- Check file-writer construction when writing envelope to path. ([#1036](https://github.com/getsentry/sentry-native/pull/1036)) + ## 0.7.8 **Features**: - Let the envelope serialization stream directly to the file. ([#1021](https://github.com/getsentry/sentry-native/pull/1021)) -- Support 16kb page sizes on Android 15 ([#1028](https://github.com/getsentry/sentry-native/pull/1028)) +- Support 16kb page sizes on Android 15. ([#1028](https://github.com/getsentry/sentry-native/pull/1028)) ## 0.7.7 diff --git a/include/sentry.h b/include/sentry.h index 29df6ae5d..5753c2cef 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -1366,6 +1366,9 @@ SENTRY_API sentry_uuid_t sentry_capture_event(sentry_value_t event); * Captures an exception to be handled by the backend. * * This is safe to be called from a crashing thread and may not return. + * + * Note: The `crashpad` client currently supports this only on Windows. `inproc` + * and `breakpad` support it on all platforms. */ SENTRY_EXPERIMENTAL_API void sentry_handle_exception( const sentry_ucontext_t *uctx); diff --git a/scripts/run_tests.ps1 b/scripts/run_tests.ps1 new file mode 100644 index 000000000..0f5345d76 --- /dev/null +++ b/scripts/run_tests.ps1 @@ -0,0 +1,40 @@ +param ( + [switch]$Unit = $false, + [switch]$Clean = $false, + [string]$Keyword = "", + [int]$Parallelism = 1, + [switch]$WithoutCrashpadWer = $false +) + +$update_test_discovery = Join-Path -Path $PSScriptRoot -ChildPath "update_test_discovery.ps1" +& $update_test_discovery + +if ($Clean -or -not (Test-Path .\.venv)) +{ + Remove-Item -Recurse -Force .\.venv\ -ErrorAction SilentlyContinue + python3.exe -m venv .venv + .\.venv\Scripts\pip.exe install --upgrade --requirement .\tests\requirements.txt +} + +$pytestCommand = ".\.venv\Scripts\pytest.exe .\tests\ --verbose" + +if ($Parallelism -gt 1) +{ + $pytestCommand += " -n $Parallelism" +} + +if (-not $WithoutCrashpadWer -and -not $Unit) +{ + $pytestCommand += " --with_crashpad_wer" +} + +if ($Keyword) +{ + $pytestCommand += " -k `"$Keyword`"" +} +elseif ($Unit) +{ + $pytestCommand += " -k `"unit`"" +} + +Invoke-Expression $pytestCommand \ No newline at end of file diff --git a/scripts/update_test_discovery.ps1 b/scripts/update_test_discovery.ps1 new file mode 100644 index 000000000..0a58f8e49 --- /dev/null +++ b/scripts/update_test_discovery.ps1 @@ -0,0 +1,7 @@ +Get-ChildItem -Path 'tests/unit/*.c' | ForEach-Object { + Get-Content $_.FullName | ForEach-Object { + if ($_ -match 'SENTRY_TEST\(([^)]+)\)') { + $_ -replace 'SENTRY_TEST\(([^)]+)\)', 'XX($1)' + } + } +} | Sort-Object | Where-Object { $_ -notmatch 'define' } | Get-Unique | Set-Content 'tests/unit/tests.inc' diff --git a/src/path/sentry_path_windows.c b/src/path/sentry_path_windows.c index bd989121f..b55ebbdf3 100644 --- a/src/path/sentry_path_windows.c +++ b/src/path/sentry_path_windows.c @@ -273,6 +273,9 @@ bool sentry__path_filename_matches(const sentry_path_t *path, const char *filename) { sentry_path_t *fn = sentry__path_from_str(filename); + if (!fn) { + return false; + } bool matches = _wcsicmp(sentry__path_filename(path), fn->path) == 0; sentry__path_free(fn); return matches; @@ -282,6 +285,9 @@ bool sentry__path_ends_with(const sentry_path_t *path, const char *suffix) { sentry_path_t *s = sentry__path_from_str(suffix); + if (!s) { + return false; + } size_t pathlen = wcslen(path->path); size_t suffixlen = wcslen(s->path); if (suffixlen > pathlen) { @@ -604,9 +610,9 @@ sentry__filewriter_write( } while (buf_len > 0) { size_t n = fwrite(buf, 1, buf_len, filewriter->f); - if (n < 0 && (errno == EAGAIN || errno == EINTR)) { + if (n == 0 && errno == EINVAL) { continue; - } else if (n <= 0) { + } else if (n < buf_len) { break; } filewriter->byte_count += n; diff --git a/src/sentry_envelope.c b/src/sentry_envelope.c index cffcb5e6e..e173e9494 100644 --- a/src/sentry_envelope.c +++ b/src/sentry_envelope.c @@ -477,6 +477,9 @@ sentry_envelope_write_to_path( const sentry_envelope_t *envelope, const sentry_path_t *path) { sentry_filewriter_t *fw = sentry__filewriter_new(path); + if (!fw) { + return 1; + } if (envelope->is_raw) { return envelope->contents.raw.payload_len diff --git a/tests/unit/test_envelopes.c b/tests/unit/test_envelopes.c index 803fb4730..8d0de1fc5 100644 --- a/tests/unit/test_envelopes.c +++ b/tests/unit/test_envelopes.c @@ -253,3 +253,19 @@ SENTRY_TEST(write_envelope_to_file_null) sentry_envelope_free(empty_envelope); } + +SENTRY_TEST(write_envelope_to_invalid_path) +{ + sentry_envelope_t *envelope = create_test_envelope(); + const char *test_file_str + = "./directory_that_does_not_exist/sentry_test_envelope"; + sentry_path_t *test_file_path = sentry__path_from_str(test_file_str); + + int rv = sentry_envelope_write_to_file(envelope, test_file_str); + TEST_CHECK_INT_EQUAL(rv, 1); + + sentry__path_remove(test_file_path); + sentry__path_free(test_file_path); + sentry_envelope_free(envelope); + sentry_close(); +} diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index 0f0db85db..cc7920bc1 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -137,3 +137,4 @@ XX(value_string_n) XX(value_unicode) XX(value_wrong_type) XX(write_envelope_to_file_null) +XX(write_envelope_to_invalid_path)