|
7 | 7 |
|
8 | 8 | #include "pack.h" |
9 | 9 |
|
10 | | -#include "odb.h" |
11 | 10 | #include "delta.h" |
12 | | -#include "sha1_lookup.h" |
13 | | -#include "mwindow.h" |
14 | 11 | #include "futils.h" |
| 12 | +#include "mwindow.h" |
| 13 | +#include "odb.h" |
15 | 14 | #include "oid.h" |
| 15 | +#include "sha1_lookup.h" |
| 16 | +#include "zstream.h" |
16 | 17 |
|
17 | 18 | #include <zlib.h> |
18 | 19 |
|
@@ -845,64 +846,60 @@ void git_packfile_stream_dispose(git_packfile_stream *obj) |
845 | 846 | static int packfile_unpack_compressed( |
846 | 847 | git_rawobj *obj, |
847 | 848 | struct git_pack_file *p, |
848 | | - git_mwindow **w_curs, |
849 | | - off64_t *curpos, |
| 849 | + git_mwindow **mwindow, |
| 850 | + off64_t *position, |
850 | 851 | size_t size, |
851 | 852 | git_object_t type) |
852 | 853 | { |
853 | | - size_t buf_size; |
854 | | - int st; |
855 | | - z_stream stream; |
856 | | - unsigned char *buffer, *in; |
857 | | - |
858 | | - GIT_ERROR_CHECK_ALLOC_ADD(&buf_size, size, 1); |
859 | | - buffer = git__calloc(1, buf_size); |
860 | | - GIT_ERROR_CHECK_ALLOC(buffer); |
| 854 | + git_zstream zstream = GIT_ZSTREAM_INIT; |
| 855 | + size_t buffer_len, total = 0; |
| 856 | + char *data = NULL; |
| 857 | + int error; |
861 | 858 |
|
862 | | - memset(&stream, 0, sizeof(stream)); |
863 | | - stream.next_out = buffer; |
864 | | - stream.avail_out = (uInt)buf_size; |
865 | | - stream.zalloc = use_git_alloc; |
866 | | - stream.zfree = use_git_free; |
| 859 | + GIT_ERROR_CHECK_ALLOC_ADD(&buffer_len, size, 1); |
| 860 | + data = git__calloc(1, buffer_len); |
| 861 | + GIT_ERROR_CHECK_ALLOC(data); |
867 | 862 |
|
868 | | - st = inflateInit(&stream); |
869 | | - if (st != Z_OK) { |
870 | | - git__free(buffer); |
| 863 | + if ((error = git_zstream_init(&zstream, GIT_ZSTREAM_INFLATE)) < 0) { |
871 | 864 | git_error_set(GIT_ERROR_ZLIB, "failed to init zlib stream on unpack"); |
872 | | - |
873 | | - return -1; |
| 865 | + goto out; |
874 | 866 | } |
875 | 867 |
|
876 | 868 | do { |
877 | | - in = pack_window_open(p, w_curs, *curpos, &stream.avail_in); |
878 | | - stream.next_in = in; |
879 | | - st = inflate(&stream, Z_FINISH); |
880 | | - git_mwindow_close(w_curs); |
| 869 | + size_t bytes = buffer_len - total; |
| 870 | + unsigned int window_len; |
| 871 | + unsigned char *in; |
881 | 872 |
|
882 | | - if (!stream.avail_out) |
883 | | - break; /* the payload is larger than it should be */ |
| 873 | + in = pack_window_open(p, mwindow, *position, &window_len); |
884 | 874 |
|
885 | | - if (st == Z_BUF_ERROR && in == NULL) { |
886 | | - inflateEnd(&stream); |
887 | | - git__free(buffer); |
888 | | - return GIT_EBUFS; |
| 875 | + if ((error = git_zstream_set_input(&zstream, in, window_len)) < 0 || |
| 876 | + (error = git_zstream_get_output_chunk(data + total, &bytes, &zstream)) < 0) { |
| 877 | + git_mwindow_close(mwindow); |
| 878 | + goto out; |
889 | 879 | } |
890 | 880 |
|
891 | | - *curpos += stream.next_in - in; |
892 | | - } while (st == Z_OK || st == Z_BUF_ERROR); |
| 881 | + git_mwindow_close(mwindow); |
893 | 882 |
|
894 | | - inflateEnd(&stream); |
| 883 | + *position += window_len - zstream.in_len; |
| 884 | + total += bytes; |
| 885 | + } while (total < size); |
895 | 886 |
|
896 | | - if ((st != Z_STREAM_END) || stream.total_out != size) { |
897 | | - git__free(buffer); |
| 887 | + if (total != size || !git_zstream_eos(&zstream)) { |
898 | 888 | git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream"); |
899 | | - return -1; |
| 889 | + error = -1; |
| 890 | + goto out; |
900 | 891 | } |
901 | 892 |
|
902 | 893 | obj->type = type; |
903 | 894 | obj->len = size; |
904 | | - obj->data = buffer; |
905 | | - return 0; |
| 895 | + obj->data = data; |
| 896 | + |
| 897 | +out: |
| 898 | + git_zstream_free(&zstream); |
| 899 | + if (error) |
| 900 | + git__free(data); |
| 901 | + |
| 902 | + return error; |
906 | 903 | } |
907 | 904 |
|
908 | 905 | /* |
|
0 commit comments