summaryrefslogtreecommitdiff
path: root/lib/sha.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2003-02-18 19:00:40 +0000
committerJim Meyering <jim@meyering.net>2003-02-18 19:00:40 +0000
commit714f398d7ffde29809ed729373d99b9e7d142afb (patch)
tree2c92075bb8132225d1d42198589d052f89976158 /lib/sha.c
parent7496bc25b0f925693021d89f91d972c860f959b5 (diff)
downloadcoreutils-714f398d7ffde29809ed729373d99b9e7d142afb.tar.xz
(sha_stream) [BLOCKSIZE]: Move definition to top of file.
Ensure that it is a multiple of 64. Rearrange loop exit tests so as to avoid performing an additional fread after encountering an error or EOF.
Diffstat (limited to 'lib/sha.c')
-rw-r--r--lib/sha.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/lib/sha.c b/lib/sha.c
index a75b8cf89..18d7f190f 100644
--- a/lib/sha.c
+++ b/lib/sha.c
@@ -1,7 +1,7 @@
/* sha.c - Functions to compute the SHA1 hash (message-digest) of files
or blocks of memory. Complies to the NIST specification FIPS-180-1.
- Copyright (C) 2000, 2001 Scott G. Miller
+ Copyright (C) 2000, 2001, 2003 Scott G. Miller
Credits:
Robert Klep <robert@ilse.nl> -- Expansion function fix
@@ -41,6 +41,13 @@
# define SWAP(n) (n)
#endif
+#define BLOCKSIZE 4096
+/* Ensure that BLOCKSIZE is a multiple of 64. */
+#if BLOCKSIZE % 64 != 0
+/* FIXME-someday (soon?): use #error instead of this kludge. */
+"invalid BLOCKSIZE"
+#endif
+
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
@@ -118,8 +125,6 @@ sha_finish_ctx (struct sha_ctx *ctx, void *resbuf)
int
sha_stream (FILE *stream, void *resblock)
{
- /* Important: BLOCKSIZE must be a multiple of 64. */
-#define BLOCKSIZE 4096
struct sha_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
@@ -137,19 +142,31 @@ sha_stream (FILE *stream, void *resblock)
sum = 0;
/* Read block. Take care for partial reads. */
- do
+ while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
- }
- while (sum < BLOCKSIZE && n != 0);
- if (n == 0 && ferror (stream))
- return 1;
- /* If end of file is reached, end the loop. */
- if (n == 0)
- break;
+ if (sum == BLOCKSIZE)
+ break;
+
+ if (n == 0)
+ {
+ /* Check for the error flag IFF N == 0, so that we don't
+ exit the loop after a partial read due to e.g., EAGAIN
+ or EWOULDBLOCK. */
+ if (ferror (stream))
+ return 1;
+ goto process_partial_block;
+ }
+
+ /* We've read at least one byte, so ignore errors. But always
+ check for EOF, since feof may be true even though N > 0.
+ Otherwise, we could end up calling fread after EOF. */
+ if (feof (stream))
+ goto process_partial_block;
+ }
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
@@ -157,7 +174,9 @@ sha_stream (FILE *stream, void *resblock)
sha_process_block (buffer, BLOCKSIZE, &ctx);
}
- /* Add the last bytes if necessary. */
+ process_partial_block:;
+
+ /* Process any remaining bytes. */
if (sum > 0)
sha_process_bytes (buffer, sum, &ctx);