diff --git a/src/amiga/map.c b/src/amiga/map.c index 2fb065c8b..c601de724 100755 --- a/src/amiga/map.c +++ b/src/amiga/map.c @@ -24,18 +24,15 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs return -1; } - if((out->data = malloc(len))) { - p_lseek(fd, offset, SEEK_SET); - p_read(fd, out->data, len); - } + out->data = malloc(len); + GITERR_CHECK_ALLOC(out->data); - if (!out->data || (out->data == MAP_FAILED)) { - giterr_set(GITERR_OS, "Failed to mmap. Could not write data"); + if (p_lseek(fd, offset, SEEK_SET) < 0 || p_read(fd, out->data, len) != len) + giterr_set(GITERR_OS, "mmap emulation failed"); return -1; } out->len = len; - return 0; } diff --git a/src/blob.c b/src/blob.c index 699adec6b..6267ae7b2 100644 --- a/src/blob.c +++ b/src/blob.c @@ -68,6 +68,7 @@ static int write_file_stream( int fd, error; char buffer[4096]; git_odb_stream *stream = NULL; + ssize_t read_len, written = 0; if ((error = git_odb_open_wstream( &stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0) @@ -78,20 +79,18 @@ static int write_file_stream( return -1; } - while (!error && file_size > 0) { - ssize_t read_len = p_read(fd, buffer, sizeof(buffer)); - - if (read_len < 0) { - giterr_set( - GITERR_OS, "Failed to create blob. Can't read whole file"); - error = -1; - } - else if (!(error = stream->write(stream, buffer, read_len))) - file_size -= read_len; + while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) { + error = stream->write(stream, buffer, read_len); + written += read_len; } p_close(fd); + if (written != file_size || read_len < 0) { + giterr_set(GITERR_OS, "Failed to read file into stream"); + error = -1; + } + if (!error) error = stream->finalize_write(oid, stream); diff --git a/src/filebuf.c b/src/filebuf.c index cfc8528e6..b9b908c8d 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -73,7 +73,7 @@ static int lock_file(git_filebuf *file, int flags) if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) { git_file source; char buffer[2048]; - size_t read_bytes; + ssize_t read_bytes; source = p_open(file->path_original, O_RDONLY); if (source < 0) { @@ -83,13 +83,18 @@ static int lock_file(git_filebuf *file, int flags) return -1; } - while ((read_bytes = p_read(source, buffer, 2048)) > 0) { + while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) { p_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } p_close(source); + + if (read_bytes < 0) { + giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original); + return -1; + } } return 0; diff --git a/src/fileops.c b/src/fileops.c index cbe3d4782..8ccf063d5 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -127,7 +127,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) /* p_read loops internally to read len bytes */ read_size = p_read(fd, buf->ptr, len); - if (read_size < 0) { + if (read_size != (ssize_t)len) { giterr_set(GITERR_OS, "Failed to read descriptor"); return -1; } diff --git a/src/odb.c b/src/odb.c index 0e03e40ee..0d3d809f7 100644 --- a/src/odb.c +++ b/src/odb.c @@ -115,6 +115,7 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) int hdr_len; char hdr[64], buffer[2048]; git_hash_ctx *ctx; + ssize_t read_len; hdr_len = format_object_header(hdr, sizeof(hdr), size, type); @@ -123,19 +124,20 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) git_hash_update(ctx, hdr, hdr_len); - while (size > 0) { - ssize_t read_len = p_read(fd, buffer, sizeof(buffer)); - - if (read_len < 0) { - git_hash_free_ctx(ctx); - giterr_set(GITERR_OS, "Error reading file"); - return -1; - } - + while (size > 0 && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) { git_hash_update(ctx, buffer, read_len); size -= read_len; } + /* If p_read returned an error code, the read obviously failed. + * If size is not zero, the file was truncated after we originally + * stat'd it, so we consider this a read failure too */ + if (read_len < 0 || size > 0) { + git_hash_free_ctx(ctx); + giterr_set(GITERR_OS, "Error reading file for hashing"); + return -1; + } + git_hash_final(out, ctx); git_hash_free_ctx(ctx);