Skip to content

Ciphers use fire-and-forget File.WriteAllTextAsync (unawaited) #6

@SimAin

Description

@SimAin

Summary

Every cipher writes its output with File.WriteAllTextAsync(...) but never awaits the returned Task (the enclosing encode/decode methods are synchronous void). This is a fire-and-forget call: the write may not have flushed by the time the method returns, and any I/O exception is swallowed silently. The synchronous File.WriteAllText(...) should be used instead.

Why it's a bug

  • Race / data loss: the process can continue (or exit) before the async write completes. This is exactly the kind of round-trip (encode → immediately decode) the app performs; results can read stale or partial output.
  • Swallowed errors: an exception in the unawaited Task (e.g. file locked, permissions) is never observed — the user sees a "success" message while nothing was written.
  • No async benefit is gained anyway, since the call sites are synchronous and single-threaded.

Affected locations (12 calls across 6 ciphers)

  • cryptography/HistoricCiphers/CaesarCipher.cs:43, 50
  • cryptography/HistoricCiphers/VigenereCipher.cs:48, 56
  • cryptography/HistoricCiphers/SimpleSubCipher.cs:48, 56
  • cryptography/HistoricCiphers/SimpleTranspositionCipher.cs:46, 55
  • cryptography/HistoricCiphers/RailFenceCipher.cs:49, 63
  • cryptography/HistoricCiphers/PlayfairCipher.cs:59, 74

Proposed fix

Replace File.WriteAllTextAsync(writeToFile, output) with the synchronous File.WriteAllText(writeToFile, output) at all call sites. Simplest, correct, and matches the synchronous nature of these methods — no async/await plumbing needed for a single-threaded console app.

Acceptance criteria

  • All cipher writes are synchronous and complete before the method returns
  • No unawaited Task / fire-and-forget calls remain (grep WriteAllTextAsync returns nothing in HistoricCiphers/)
  • dotnet build clean; all tests pass
  • Encode → decode round-trip produces correct output reliably

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions