Repository navigation
Conversation
|
Thank you for your pull request and welcome to the Skip community. We require contributors to sign our contributor license agreement (CLA), and we don't seem to have the user(s) @Evan-Haug on file. In order for us to review and merge your code, for each noted user please add your GitHub username to Skip's .clabot file |
Author
|
@cla-bot recheck |
… or short one The aggregate cacerts file was created empty under its final name and then filled, and an existing file was reused without any check. A process death or write failure in between left an empty or truncated file that was trusted on every later launch, so libcurl had no roots and every https request failed. Write to a temporary file in the same folder, synchronize it and rename it into place. Reuse an existing aggregate only when it is non-empty and at least as large as the sum of the selected certificate files. Add Android tests: complete bundle, empty bundle rebuilt, truncated bundle rebuilt, valid bundle left untouched.
Evan-Haug
force-pushed
the
fix/cacerts-atomic-write
branch
from
October 27, 2026 22:42
809ded8 to
f079391
Compare
Author
|
@cla-bot recheck |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
setupCACerts: write the aggregate atomically and never reuse an empty or short one
AndroidBootstrap.setupCACertscreatescacerts-aggregate-<hash>.pemas an empty file under its final name, then writes the header and every certificate, and on a later launch reuses any existing file without checking it. If the process dies or a write fails between the create and the last write, the file is left empty or cut short under the final name and is trusted from then on. libcurl then has no trusted roots, so every https request fails and nothing is logged.Observed on an Android 15 arm64 emulator with an app built on this package: a 0 byte
cacerts-aggregate-*.pem(0 certificates) in the app cache, every https call failing at the certificate check; the same app with a fresh cache wrote 1,515,972 bytes (290 certificates) and connected. This reproduces on currentmain(d757c18) and tag 1.5.2.Change
synchronize()it, andrename(2)it into place, so the final name never holds a partial file. The temporary file is removed on every error path.forceis false, reuse it only if it is non-empty and at least as large as the sum of the selected certificate files (a complete aggregate is a header plus the full bytes of those files, so it is never smaller). Otherwise remove it and regenerate.setenv.Tests
Three Swift Testing tests, Android only: a complete bundle is built (four certificates, size at least the sum, no
.tmpleft); an empty bundle is rebuilt; bundles cut to 1 and 100 bytes are rebuilt, and a valid bundle is left untouched (same size and modification time).Run with
skip android teston an Android 15 arm64 emulator: the three new tests pass with this change, and with the same tests against the unmodified source the empty and truncated tests fail (the unmodified code reuses the bad file).Limits worth knowing
The size comparison is a cheap guard for files left by older versions; a file cut inside the header sized slack at its end (about 190 bytes on a typical device) would still pass it. The atomic write is what prevents this library from producing a partial file in the first place.
testEmbedInCodeResourcefailed in my environment both with and without this change (probably CRLF line endings in a Windows checkout ofResources/sample_resource.txt), so it is unrelated.🤖 Generated with Claude Code