Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ EXTRA_DIST= \
tests/08-passphrase-file.sh \
tests/09-explicit-params.sh \
tests/10-check-params.sh \
tests/11-output-finalization.sh \
tests/shared_test_functions.sh \
tests/shared_valgrind_functions.sh \
tests/test_scrypt.sh \
Expand Down
15 changes: 13 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,19 @@ scrypt_mode_enc_dec(struct scryptenc_params params,
/* Close any files we opened. */
if ((infile != stdin) && fclose(infile))
warnp("fclose");
if ((outfile != stdout) && fclose(outfile))
warnp("fclose");
if (outfile != stdout) {
if (fclose(outfile)) {
if (rc == SCRYPT_OK)
rc = SCRYPT_EWRFILE;
else
warnp("fclose");
}
} else if ((outfilename == NULL) && fflush(outfile)) {
if (rc == SCRYPT_OK)
rc = SCRYPT_EWRFILE;
else
warnp("fflush");
}

/* If we failed, print the right error message and exit. */
if (rc != SCRYPT_OK) {
Expand Down
51 changes: 51 additions & 0 deletions tests/11-output-finalization.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/sh

### Constants
input_file="${s_basename}-input.txt"
named_stderr="${s_basename}-named.stderr"
stdout_stderr="${s_basename}-stdout.stderr"

scenario_cmd() {
# /dev/full is available on Linux but not on every test platform.
if [ ! -c /dev/full ]; then
setup_check "scrypt enc named output close failure"
echo "-1" > "${c_exitfile}"
setup_check "scrypt enc named output close error"
echo "-1" > "${c_exitfile}"
setup_check "scrypt enc stdout flush failure"
echo "-1" > "${c_exitfile}"
setup_check "scrypt enc stdout flush error"
echo "-1" > "${c_exitfile}"
return
fi

# Keep the output small enough that the write error is delayed until
# fclose(3) or fflush(3), rather than being returned by fwrite(3).
printf "x" > "${input_file}"

# A delayed failure while closing a named output file must fail the
# command, rather than merely printing a warning and exiting 0.
setup_check "scrypt enc named output close failure"
printf "%s\n" "${password}" | "${bindir}/scrypt" \
enc --logN 10 -r 1 -p 1 \
--passphrase dev:stdin-once \
"${input_file}" /dev/full 2> "${named_stderr}"
expected_exitcode 1 $? > "${c_exitfile}"

setup_check "scrypt enc named output close error"
grep -q "Error writing file: /dev/full" "${named_stderr}"
echo $? > "${c_exitfile}"

# stdout also needs an explicit flush check; exit(3) cannot propagate a
# delayed stdio error into the process exit status.
setup_check "scrypt enc stdout flush failure"
printf "%s\n" "${password}" | "${bindir}/scrypt" \
enc --logN 10 -r 1 -p 1 \
--passphrase dev:stdin-once \
"${input_file}" > /dev/full 2> "${stdout_stderr}"
expected_exitcode 1 $? > "${c_exitfile}"

setup_check "scrypt enc stdout flush error"
grep -q "Error writing file: standard output" "${stdout_stderr}"
echo $? > "${c_exitfile}"
}