diff options
| author | Mattias Andrée <maandree@kth.se> | 2022-07-07 15:32:34 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2022-07-07 15:32:34 +0200 | 
| commit | c44852846418d687027912d4150404feed0161f9 (patch) | |
| tree | 8e08a8420179dfe2909c9a77573c5f537a85818c /sum_fd.c | |
| parent | Don't marshal w (diff) | |
| download | libsha2-c44852846418d687027912d4150404feed0161f9.tar.gz libsha2-c44852846418d687027912d4150404feed0161f9.tar.bz2 libsha2-c44852846418d687027912d4150404feed0161f9.tar.xz | |
Use malloc by default but allow bounded alloca
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | sum_fd.c | 31 | 
1 files changed, 31 insertions, 0 deletions
| @@ -7,17 +7,42 @@ libsha2_sum_fd(int fd, enum libsha2_algorithm algorithm, void *restrict hashsum)  {  	struct libsha2_state state;  	ssize_t r; +#ifndef _WIN32  	struct stat attr; +#endif  	size_t blksize = 4096;  	char *restrict chunk;  	if (libsha2_init(&state, algorithm) < 0)  		return -1; +#ifndef _WIN32  	if (fstat(fd, &attr) == 0 && attr.st_blksize > 0)  		blksize = (size_t)(attr.st_blksize); +#endif +#if ALLOCA_LIMIT > 0 +	if (blksize > (size_t)ALLOCA_LIMIT) { +		blksize = (size_t)ALLOCA_LIMIT; +		blksize -= blksize % sizeof(((struct libsha2_state)NULL)->chunk); +		if (!blksize) +			blksize = sizeof(((struct libsha2_state)NULL)->chunk); +	} +# if defined(__clang__) +	/* We are using a limit so it's just like declaring an array +	 * in a function, except we might use less of the stack. */ +#  pragma clang diagnostic push +#  pragma clang diagnostic ignored "-Walloca" +# endif  	chunk = alloca(blksize); +# if defined(__clang__) +#  pragma clang diagnostic pop +# endif +#else +	chunk = malloc(blksize); +	if (!chunk) +		return -1; +#endif  	for (;;) {  		r = read(fd, chunk, blksize); @@ -26,11 +51,17 @@ libsha2_sum_fd(int fd, enum libsha2_algorithm algorithm, void *restrict hashsum)  				break;  			if (errno == EINTR)  				continue; +#if ALLOCA_LIMIT <= 0 +			free(chunk); +#endif  			return -1;  		}  		libsha2_update(&state, chunk, (size_t)r * 8);  	}  	libsha2_digest(&state, NULL, 0, hashsum); +#if ALLOCA_LIMIT <= 0 +       free(chunk); +#endif  	return 0;  } | 
