]> git.proxmox.com Git - libgit2.git/commitdiff
Properly handle p_reads
authorVicent Marti <tanoku@gmail.com>
Tue, 11 Sep 2012 21:05:24 +0000 (23:05 +0200)
committerVicent Marti <tanoku@gmail.com>
Tue, 11 Sep 2012 21:05:24 +0000 (23:05 +0200)
src/amiga/map.c
src/blob.c
src/filebuf.c
src/fileops.c
src/odb.c

index 2fb065c8b153ffaf0398911ead0362306d89c6be..c601de7243d4b6dc80daea8820fcdfb39cea3a7e 100755 (executable)
@@ -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;
 }
 
index 699adec6b7f1abe8974556fb0b0e816d95cac250..6267ae7b2d08f83e8fcb7b9218f395fe9ab4601c 100644 (file)
@@ -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);
 
index cfc8528e62ac0d3573e3b7a31326fa6bd618534c..b9b908c8da18e9a679ab6de24b0991d91267c434 100644 (file)
@@ -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;
index cbe3d47820f64db90bdeb1bdce617063675dd537..8ccf063d5d69e9390752d77e86a8faf81f97f062 100644 (file)
@@ -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;
        }
index 0e03e40eefa8c66facd14f16fbe549cba0f78f2c..0d3d809f7bc7bdd96a14437a5b7a4d7dc330a0f1 100644 (file)
--- 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);