Commit message: memdisk
 (.)
CVE: CVE-2018-7725
CWE: CWE-119
Vulnerability description: An issue was discovered in ZZIPlib 0.13.68. An invalid memory address dereference was discovered in zzip_disk_fread in mmapped.c. The vulnerability causes an application crash, which leads to denial of service.

Project: zziplib
File: memdisk.c

zzip_mem_disk_fdopen(int fd)
{
    ZZIP_DISK* disk = zzip_disk_mmap(fd);
    if (! disk) { perror(error[_zzip_mem_disk_fdopen_fail]); return 0; }
    ___ ZZIP_MEM_DISK* dir = zzip_mem_disk_new();
    zzip_mem_disk_load(dir, disk);
    return dir; ____;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_new(void)
{
    return calloc(1, sizeof(ZZIP_MEM_DISK)); 
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_fclose (ZZIP_MEM_DISK_FILE* file) 
{
    return zzip_disk_fclose (file);
}

Project: zziplib
File: mmapped.c

static char* _zzip_restrict _zzip_strndup(char* p, int maxlen)
{
    if (! p) return 0;
    ___ char* r = malloc (maxlen+1);
    if (! r) return r;
    strncpy (r, p, maxlen);
    r[maxlen] = '\0';
    return r; ____;
}

Project: zziplib
File: mmapped.c

zzip_disk_feof (ZZIP_DISK_FILE* file)
{
    return ! file || ! file->avail;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_load(ZZIP_MEM_DISK* dir, ZZIP_DISK* disk)
{
    if (! dir || ! disk) { errno=EINVAL; return -1; }
    if (dir->list) zzip_mem_disk_unload(dir);
    ___ long count = 0;
    ___ struct zzip_disk_entry* entry = zzip_disk_findfirst(disk);
    for (; entry ; entry = zzip_disk_findnext(disk, entry)) {
	ZZIP_MEM_ENTRY* item = zzip_mem_entry_new(disk, entry);
	if (! item) goto error;
	if (dir->last) { dir->last->zz_next = item; }    /* chain last */
	else { dir->list = item; }; dir->last = item;    /* to earlier */
	count++;
    } ____;
    dir->disk = disk;
    return count; ____;
 error:
    zzip_mem_disk_unload (dir); 
    return -1;
}

Project: zziplib
File: mmapped.c

zzip_disk_entry_strdup_name(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if (! disk || ! entry) return 0;

    ___ char* name; zzip_size_t len;
    struct zzip_file_header* file;
    if ((len = zzip_disk_entry_namlen (entry)))
	name = zzip_disk_entry_to_filename (entry);
    else if ((file = zzip_disk_entry_to_file_header (disk, entry)) &&
	     (len = zzip_file_header_namlen (file)))
	name = zzip_file_header_to_filename (file);
    else
	return 0;

    if (disk->buffer > name || name+len > disk->endbuf)
	return 0;
    
    return  _zzip_strndup (name, len); ____;
}

Project: zziplib
File: mmapped.c

zzip_disk_entry_strdup_comment(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if (! disk || ! entry) return 0;

    ___ char* text; zzip_size_t len;
    if ((len = zzip_disk_entry_comment (entry)))
	text = zzip_disk_entry_to_comment (entry);
    else
	return 0;

    if (disk->buffer > text || text+len > disk->endbuf)
	return 0;
    
    return  _zzip_strndup (text, len); ____;
}

Project: zziplib
File: memdisk.c

static void foo (short zz_datatype) {
    switch (zz_datatype) {
    case 0x0001: /* ZIP64 extended information extra field */
    case 0x0007: /* AV Info */
    case 0x0008: /* Reserved for future Unicode file name data (PFS) */
    case 0x0009: /* OS/2 */
    case 0x000a: /* NTFS */
    case 0x000c: /* OpenVMS */
    case 0x000d: /* Unix */
    case 0x000e: /* Reserved for file stream and fork descriptors */
    case 0x000f: /* Patch Descriptor */
    case 0x0014: /* PKCS#7 Store for X.509 Certificates */
    case 0x0015: /* X.509 Certificate ID and Signature for file */
    case 0x0016: /* X.509 Certificate ID for Central Directory */
    case 0x0017: /* Strong Encryption Header */
    case 0x0018: /* Record Management Controls */
    case 0x0019: /* PKCS#7 Encryption Recipient Certificate List */
    case 0x0065: /* IBM S/390, AS/400 attributes - uncompressed */
    case 0x0066: /* Reserved for IBM S/390, AS/400 attr - compressed */
    case 0x07c8: /* Macintosh */
    case 0x2605: /* ZipIt Macintosh */
    case 0x2705: /* ZipIt Macintosh 1.3.5+ */
    case 0x2805: /* ZipIt Macintosh 1.3.5+ */
    case 0x334d: /* Info-ZIP Macintosh */
    case 0x4341: /* Acorn/SparkFS  */
    case 0x4453: /* Windows NT security descriptor (binary ACL) */
    case 0x4704: /* VM/CMS */
    case 0x470f: /* MVS */
    case 0x4b46: /* FWKCS MD5 (see below) */
    case 0x4c41: /* OS/2 access control list (text ACL) */
    case 0x4d49: /* Info-ZIP OpenVMS */
    case 0x4f4c: /* Xceed original location extra field */
    case 0x5356: /* AOS/VS (ACL) */
    case 0x5455: /* extended timestamp */
    case 0x554e: /* Xceed unicode extra field */
    case 0x5855: /* Info-ZIP Unix (original, also OS/2, NT, etc) */
    case 0x6542: /* BeOS/BeBox */
    case 0x756e: /* ASi Unix */
    case 0x7855: /* Info-ZIP Unix (new) */
    case 0xfd4a: /* SMS/QDOS */
    }
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_close(ZZIP_MEM_DISK* _zzip_restrict dir) 
{
    if (dir) {
	zzip_mem_disk_unload (dir);
	zzip_disk_close(dir->disk);
	free (dir);
    }
}

Project: zziplib
File: mmapped.c

zzip_disk_close(ZZIP_DISK* disk)
{
    if (! disk) return 0;
    if (disk->mapped != -1) return zzip_disk_munmap (disk);
    free (disk->buffer);
    free (disk);
    return 0;
}

Project: zziplib
File: mmapped.c

zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
{
    /* keep this in sync with zzip_mem_entry_fopen */
    struct zzip_file_header* header = 
	zzip_disk_entry_to_file_header (disk, entry);
    if (! header) return 0;
    ___ ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE));
    if (! file) return file;
    file->buffer = disk->buffer;
    file->endbuf = disk->endbuf;
    file->avail = zzip_file_header_usize (header);

    if (! file->avail || zzip_file_header_data_stored (header))
    { file->stored = zzip_file_header_to_data (header); return file; }

    file->stored = 0;
    file->zlib.opaque = 0;
    file->zlib.zalloc = Z_NULL;
    file->zlib.zfree = Z_NULL;
    file->zlib.avail_in = zzip_file_header_csize (header);
    file->zlib.next_in = zzip_file_header_to_data (header);

    if (! zzip_file_header_data_deflated (header) ||
	inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK)
    { free (file); return 0; }

    return file; ____;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_fopen (ZZIP_MEM_DISK* dir, char* filename) 
{
    ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfile (dir, filename, 0, 0);
    if (! entry) return 0; else return zzip_mem_entry_fopen (dir, entry);
}

Project: zziplib
File: mmapped.c

zzip_disk_findfile(ZZIP_DISK* disk, char* filename, 
		    struct zzip_disk_entry* after, zzip_strcmp_fn_t compare)
{
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
				     : zzip_disk_findnext (disk, after));
    if (! compare) 
	compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? 
				      (_zzip_strcasecmp) : (strcmp));
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
    {
	/* filenames within zip files are often not null-terminated! */
	char* realname = zzip_disk_entry_strdup_name (disk, entry);
	if (realname && ! compare(filename, realname))
	{
	    free (realname);
	    return entry;
	}
	free (realname);
    }
    return 0;
}

Project: zziplib
File: memdisk.h

zzip_mem_entry_to_data(ZZIP_MEM_ENTRY* entry) {
    if (! entry) return 0;
    return _zzip_mem_entry_to_data(entry); }

Project: zziplib
File: mmapped.c

zzip_disk_mmap(int fd)
{
    struct stat st;
    if (fstat (fd, &st) || !st.st_size) return 0;
    ___ ZZIP_DISK* disk = zzip_disk_new (); if (! disk) return 0;
    disk->buffer = _zzip_mmap (& zzip->mapped, fd, 0, st.st_size);
    if (disk->buffer == MAP_FAILED) { free (disk); return 0; }
    disk->endbuf = disk->buffer + st.st_size;
    return disk; ____;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_open(char* filename)
{
    ZZIP_DISK* disk = zzip_disk_open(filename);
    if (! disk) { perror(error[_zzip_mem_disk_open_fail]); return 0; }
    ___ ZZIP_MEM_DISK* dir = zzip_mem_disk_new();
    zzip_mem_disk_load(dir, disk);
    return dir; ____;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file)
{
    return zzip_disk_feof (file);
}

Project: zziplib
File: memdisk.h

zzip_mem_entry_strdup_name(ZZIP_MEM_ENTRY* entry) {
    if (! entry) return 0;
    return _zzip_mem_entry_strdup_name(entry); }

Project: zziplib
File: mmapped.c

zzip_disk_new(void)
{
    ZZIP_DISK* disk = malloc(sizeof(disk));
    if (! disk) return disk;
    zzip_disk_init (disk, 0, 0);
    return disk;
}

Project: zziplib
File: mmapped.c

static int _zzip_strcasecmp(char* __zzip_restrict a, char* _zzip_restrict b)
{
    if (! a) return (b) ? 1 : 0;
    if (! b) return -1;
    while (1) 
    {
	int v = tolower(*a) - tolower(*b);
	if (v) return v;
	if (! *a) return 1;
	if (! *b) return -1;
	a++; b++;
    }
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_findfile(ZZIP_MEM_DISK* dir, 
                       char* filename, ZZIP_MEM_ENTRY* after,
		       zzip_strcmp_fn_t compare) 
{
    ZZIP_MEM_ENTRY* entry = (! after ? dir->list : after->zz_next);
    if (! compare) compare = (zzip_strcmp_fn_t) (strcmp);
    for (; entry ; entry = entry->zz_next) {
	if (! compare (filename, entry->zz_name)) {
	    return entry;
	}
    }
    return 0;
}

Project: zziplib
File: mmapped.c

zzip_disk_init(ZZIP_DISK* disk, char* buffer, zzip_size_t buflen)
{
    disk->buffer = buffer;
    disk->endbuf = buffer+buflen;
    disk->reserved = 0;
    disk->flags = 0;
    disk->mapped = 0;
    /* do not touch disk->user */
    /* do not touch disk->code */
    return 0;
}

Project: zziplib
File: mmapped.c

zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, 
		    struct zzip_disk_entry* after,
		    zzip_fnmatch_fn_t compare, int flags)
{
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
				     : zzip_disk_findnext (disk, after));
    if (! compare) { 
	compare = (zzip_fnmatch_fn_t) _zzip_fnmatch; 
	if (disk->flags&1) disk->flags |= _zzip_fnmatch_CASEFOLD;
    }
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
    {
	/* filenames within zip files are often not null-terminated! */
	char* realname = zzip_disk_entry_strdup_name(disk, entry);
	if (realname && ! compare(filespec, realname, flags))
	{
	    free (realname);
	    return entry;
	}
	free (realname);
    }
    return 0;
}

Project: zziplib
File: memdisk.h

zzip_mem_disk_findfirst(ZZIP_MEM_DISK* dir) {
    if (! dir) return 0;
    return _zzip_mem_disk_findfirst(dir); }

Project: zziplib
File: memdisk.h

zzip_mem_entry_to_name(ZZIP_MEM_ENTRY* entry) {
    if (! entry) return 0;
    return _zzip_mem_entry_to_name(entry); }

Project: zziplib
File: mmapped.c

zzip_disk_fread (void* ptr, zzip_size_t sized, zzip_size_t nmemb,
		 ZZIP_DISK_FILE* file)
{
    zzip_size_t size = sized*nmemb;
    if (size > file->avail) size = file->avail;
    if (file->stored)
    {
	memcpy (ptr, file->stored, size);
	file->stored += size;
	file->avail -= size;
	return size;
    }
    
    file->zlib.avail_out = sized*nmemb;
    file->zlib.next_out = ptr;
    ___ zzip_size_t total_old = file->zlib.total_out;
    ___ int err = inflate (& file->zlib, Z_NO_FLUSH);
    if (err == Z_STREAM_END)
	file->avail = 0;
    else if (err == Z_OK)
	file->avail -= file->zlib.total_out - total_old;
    else
	return 0;
    return file->zlib.total_out - total_old;
    ____;____;
}

Project: zziplib
File: mmapped.c

zzip_disk_entry_to_file_header(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    char* file_header = /* (struct zzip_file_header*) */
	(disk->buffer + zzip_disk_entry_fileoffset (entry));
    if (disk->buffer > file_header || file_header >= disk->endbuf) 
	return 0;
    return (struct zzip_file_header*) file_header;
}

Project: zziplib
File: memdisk.h

_zzip_inline ZZIP_DISK* zzip_disk (ZZIP_MEM_DISK* dir) { return dir->disk; }

Project: zziplib
File: mmapped.c

zzip_disk_fclose (ZZIP_DISK_FILE* file)
{
    if (! file->stored)
	inflateEnd (& file->zlib);
    free (file);
    return 0;
}

Project: zziplib
File: memdisk.c

zzip_mem_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry) 
{
    if (! disk || ! entry) { errno=EINVAL; return 0; }
    ___ ZZIP_MEM_ENTRY* item = calloc(1, sizeof(*item));
    if (! item) return 0; /* errno=ENOMEM; */
    ___ struct zzip_file_header* header = 
	zzip_disk_entry_to_file_header(disk, entry);
    /*  there is a number of duplicated information in the file header
     *  or the disk entry block. Theoretically some part may be missing
     *  that exists in the other, ... but we will prefer the disk entry.
     */
    item->zz_comment =   zzip_disk_entry_strdup_comment(disk, entry);
    item->zz_name =      zzip_disk_entry_strdup_name(disk, entry);
    item->zz_data =      zzip_file_header_to_data(header);
    item->zz_flags =     zzip_disk_entry_get_flags(entry);
    item->zz_compr =     zzip_disk_entry_get_compr(entry);
    item->zz_crc32 =     zzip_disk_entry_get_crc32(entry);
    item->zz_csize =     zzip_disk_entry_get_csize(entry);
    item->zz_usize =     zzip_disk_entry_get_usize(entry);
    item->zz_diskstart = zzip_disk_entry_get_diskstart(entry);
    item->zz_filetype =  zzip_disk_entry_get_filetype(entry);

    {   /* copy the extra blocks to memory as well */
	int     ext1 = zzip_disk_entry_get_extras(entry);
	char* R ptr1 = zzip_disk_entry_to_extras(entry);
	int     ext2 = zzip_file_header_get_extras(header);
	char* R ptr2 = zzip_file_header_to_extras(header);
	
	if (ext1) {
	    void* mem = malloc (ext1+2);
	    item->zz_ext[1] = mem;
	    memcpy (mem, ptr1, ext1);
	    ((char*)(mem))[ext1+0] = 0; 
	    ((char*)(mem))[ext1+1] = 0;
	}	    
	if (ext2) {
	    void* mem = malloc (ext2+2);
	    item->zz_ext[2] = mem;
	    memcpy (mem, ptr2, ext2);
	    ((char*)(mem))[ext2+0] = 0; 
	    ((char*)(mem))[ext2+1] = 0;
	}	    
    }    
    {   /* override sizes/offsets with zip64 values for largefile support */
	zzip_extra_zip64* block = (zzip_extra_zip64*)
	    zzip_mem_entry_extra_block (item, ZZIP_EXTRA_zip64);
	if (block) {
	    item->zz_usize  =    __zzip_get64(block->z_usize);
	    item->zz_csize  =    __zzip_get64(block->z_csize);
	    item->zz_offset =    __zzip_get64(block->z_offset);
	    item->zz_diskstart = __zzip_get32(block->z_diskstart);
	}
    }
    /* NOTE: 
     * All information from the central directory entry is now in memory.
     * Effectivly that allows us to modify it and write it back to disk.
     */
    return item; ____;____;
}

Project: zziplib
File: memdisk.c

zzip_mem_entry_free(ZZIP_MEM_ENTRY* _zzip_restrict item) 
{
    if (item) {
	if (item->zz_ext[0]) free (item->zz_ext[0]);
	if (item->zz_ext[1]) free (item->zz_ext[1]);
	if (item->zz_ext[2]) free (item->zz_ext[2]);
	if (item->zz_comment) free (item->zz_comment);
	if (item->zz_name) free (item->zz_name);
	free (item);
    }
}

Project: zziplib
File: mmapped.c

zzip_disk_open(char* filename)
{
#  ifndef O_BINARY
#  define O_BINARY 0
#  endif
    struct stat st;
    if (stat (filename, &st) || !st.st_size) return 0;
    ___ int fd = open (filename, O_RDONLY|O_BINARY);
    if (fd <= 0) return 0;
    ___ ZZIP_DISK* disk = zzip_disk_mmap (fd);
    if (disk) return disk;
    ___ char* buffer = malloc (st.st_size);
    if (! buffer) return 0;
    if ((st.st_size == read (fd, buffer, st.st_size)) &&
	(disk = zzip_disk_new ())) 
    {
	disk->buffer = buffer;
	disk->endbuf = buffer+st.st_size;
	disk->mapped = -1;
    }else free (buffer);
    return disk; ____;____;____;
}

Project: zziplib
File: mmapped.c

static int _zzip_fnmatch(char* pattern, char* string, int flags)
{ 
    puts ("<zzip:mmapped:strcmp>");
    return strcmp (pattern, string); 
}

Project: zziplib
File: memdisk.h

zzip_mem_entry_findnext(ZZIP_MEM_ENTRY* entry) {
    if (! entry) return 0;
    return _zzip_mem_entry_findnext(entry); }

Project: zziplib
File: mmapped.c

zzip_disk_fopen (ZZIP_DISK* disk, char* filename)
{
    ZZIP_DISK_ENTRY* entry = zzip_disk_findfile (disk, filename, 0, 0);
    if (! entry) return 0; else return zzip_disk_entry_fopen (disk, entry);
}

Project: zziplib
File: mmapped.c

zzip_disk_findfirst(ZZIP_DISK* disk)
{
    if (disk->buffer > disk->endbuf-sizeof(struct zzip_disk_trailer))
	return 0;
    ___ char* p = disk->endbuf-sizeof(struct zzip_disk_trailer);
    for (; p >= disk->buffer ; p--)
    {
	char* root; /* (struct zzip_disk_entry*) */
	if (zzip_disk_trailer_check_magic(p)) {
	    root =  disk->buffer + zzip_disk_trailer_get_rootseek (
		(struct zzip_disk_trailer*)p);
	    if (root > p) 
	    {   /* the first disk_entry is after the disk_trailer? can't be! */
		zzip_size_t rootsize = zzip_disk_trailer_get_rootsize (
		    (struct zzip_disk_trailer*)p);
		if (disk->buffer+rootsize > p) continue;
		/* a common brokeness that can be fixed: we just assume the
		 * central directory was written directly before the trailer:*/
		root = p - rootsize;
	    }
	} else if (zzip_disk64_trailer_check_magic(p)) {
	    if (sizeof(void*) < 8) return 0; /* EOVERFLOW */
	    root =  disk->buffer + zzip_disk64_trailer_get_rootseek (
		(struct zzip_disk64_trailer*)p);
	    if (root > p) continue; 
	} else continue;

	if (root < disk->buffer) continue;
	if (zzip_disk_entry_check_magic(root)) 
	    return (struct zzip_disk_entry*) root;
    }____;
    return 0;
}

Project: zziplib
File: memdisk.c

zzip_mem_entry_fopen (ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry) 
{
    /* keep this in sync with zzip_disk_entry_fopen */
    ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_MEM_DISK_FILE));
    if (! file) return file;
    file->buffer = dir->disk->buffer;
    file->endbuf = dir->disk->endbuf;
    file->avail = zzip_mem_entry_usize (entry);

    if (! file->avail || zzip_mem_entry_data_stored (entry))
    { file->stored = zzip_mem_entry_to_data (entry); return file; }

    file->stored = 0;
    file->zlib.opaque = 0;
    file->zlib.zalloc = Z_NULL;
    file->zlib.zfree = Z_NULL;
    file->zlib.avail_in = zzip_mem_entry_csize (entry);
    file->zlib.next_in = zzip_mem_entry_to_data (entry);

    if (! zzip_mem_entry_data_deflated (entry) ||
	inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK)
    { free (file); return 0; }

    return file;
}

Project: zziplib
File: mmapped.c

zzip_disk_entry_to_data(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    struct zzip_file_header* file = 
	zzip_disk_entry_to_file_header(disk, entry);
    if (file) return zzip_file_header_to_data (file);
    return 0;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_findmatch(ZZIP_MEM_DISK* dir, 
                        char* filespec, ZZIP_MEM_ENTRY* after,
			zzip_fnmatch_fn_t compare, int flags)
{
    ZZIP_MEM_ENTRY* entry = (! after ? dir->list : after->zz_next);
    if (! compare) compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
    for (; entry ; entry = entry->zz_next) {
	if (! compare (filespec, entry->zz_name, flags)) {
	    return entry;
	}
    }
    return 0;
}

Project: zziplib
File: memdisk.c

zzip_mem_entry_extra_block (ZZIP_MEM_ENTRY* entry, short datatype)
{
    int i = 2;
    while (1) {
	ZZIP_EXTRA_BLOCK* ext = entry->zz_ext[i];
	if (ext) {
	    while (ext->z_datatype) {
		if (datatype == zzip_extra_block_get_datatype (ext)) {
		    return ext;
		}
		___ char* e = (char*) ext;
		e += zzip_extra_block_headerlength;
		e += zzip_extra_block_get_datasize (ext);
		ext = (void*) e; ____;
	    }
	}
	if (! i) return 0;
	i--;
    }
}

Project: zziplib
File: mmapped.c

zzip_disk_findnext(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if ((char*)entry < disk->buffer || 
	(char*)entry > disk->endbuf-sizeof(entry) ||
	! zzip_disk_entry_check_magic (entry) ||
	zzip_disk_entry_sizeto_end (entry) > 64*1024)
	return 0;
    entry = zzip_disk_entry_to_next_entry (entry);
    if ((char*)entry > disk->endbuf-sizeof(entry) ||
	! zzip_disk_entry_check_magic (entry) ||
	zzip_disk_entry_sizeto_end (entry) > 64*1024 ||
	zzip_disk_entry_skipto_end (entry) + sizeof(entry) > disk->endbuf)
	return 0;
    else
	return entry;
}

Project: zziplib
File: mmapped.c

zzip_disk_munmap(ZZIP_DISK* disk)
{
    if (! disk) return 0;
    _zzip_munmap (disk->mapped, disk->buffer, disk->endbuf-disk->buffer);
    free (disk);
    return 0;
}

Project: zziplib
File: memdisk.c

zzip_mem_disk_unload(ZZIP_MEM_DISK* dir)
{
    ZZIP_MEM_ENTRY* item = dir->list;
    while (item) {
	ZZIP_MEM_ENTRY* next = item->zz_next;
	zzip_mem_entry_free(item); item = next;
    }
    dir->list = dir->last = 0; dir->disk = 0;
}

Project: zziplib
File: memdisk.h

zzip_mem_disk_findnext(ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry) {
    if (! dir) return 0;
    return _zzip_mem_disk_findnext(dir, entry); }

Project: zziplib
File: memdisk.c

zzip_mem_disk_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
                     ZZIP_MEM_DISK_FILE* file)
{
    return zzip_disk_fread (ptr, size, nmemb, file);
}