示例#1
0
struct pkg_vulnerabilities *
read_pkg_vulnerabilities_file(const char *path, int ignore_missing, int check_sum)
{
#ifdef BOOTSTRAP
	errx(EXIT_FAILURE, "Audit functions are unsupported during bootstrap");
#else
	struct archive *a;
	struct pkg_vulnerabilities *pv;
	int fd;

	if ((fd = open(path, O_RDONLY)) == -1) {
		if (errno == ENOENT && ignore_missing)
			return NULL;
		err(EXIT_FAILURE, "Cannot open %s", path);
	}

	if ((a = archive_read_new()) == NULL)
		errx(EXIT_FAILURE, "memory allocation failed");
	
	if (archive_read_support_compression_all(a) != ARCHIVE_OK ||
	    archive_read_support_format_raw(a) != ARCHIVE_OK ||
	    archive_read_open_fd(a, fd, 65536) != ARCHIVE_OK)
		errx(EXIT_FAILURE, "Cannot open ``%s'': %s", path,
		    archive_error_string(a));

	pv = read_pkg_vulnerabilities_archive(a, check_sum);
	close(fd);

	return pv;
#endif
}
static void
test(int skip_explicitely)
{
	struct archive* a = archive_read_new();
	struct archive_entry* e;

	assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, (void*) data,
	    sizeof(data)));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	if (skip_explicitely)
		assertEqualInt(ARCHIVE_OK, archive_read_data_skip(a));

	assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	archive_read_free(a);
}
示例#3
0
Reader *Reader::read_open_filename(const char *filename, const char *cmd, bool raw) 
{
    struct archive *ar = archive_read_new();

    try {
        if(cmd) {
            if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_filter_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(raw) {
            if(archive_read_support_format_raw(ar) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_format_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(archive_read_open_filename(ar, filename, 1024) != ARCHIVE_OK)
            throw 0;

    } catch(...) {
        std::string error_msg = archive_error_string(ar);
        archive_read_free(ar);
        throw Error(error_msg);
    }

    return new Reader(ar);
}
示例#4
0
int main(int argc, const char **argv) {
    if (argc > 2) {
        fprintf(stderr, "Usage: %s [file]\n", argv[0]);
        exit(1);
    }

    struct archive *a = archive_read_new();
    archive_read_support_compression_all(a);
    archive_read_support_format_raw(a);

    int err;
    if (argc == 2) err = archive_read_open_filename(a, argv[1], BS);
    else err = archive_read_open_fd(a, 0, BS);
    if (err != ARCHIVE_OK) {
        fprintf(stderr, "Broken archive (1)\n");
        exit(1);
    }

    struct archive_entry *ae;
    err = archive_read_next_header(a, &ae);
    if (err != ARCHIVE_OK) {
        fprintf(stderr, "Broken archive (2)\n");
        exit(1);
    }

    (void) archive_read_data_into_fd(a, 1);

    archive_read_finish(a);
    exit(0);
}
static int
get_format(const char *archive)
{
	struct archive *a;
	struct archive_entry *ae;
	int found_format;
 
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_mtree(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_empty(a));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_memory(a, archive, strlen(archive)));
	// Read one header to settle the format.
	// This might return EOF or OK.
	archive_read_next_header(a, &ae);

	found_format = archive_format(a);

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));

	return found_format;
}
示例#6
0
文件: archive.c 项目: BossKing/vlc
void EnableArchiveFormats(struct archive *p_archive)
{
    //    archive_read_support_filter_bzip2(p_archive);
    //    archive_read_support_filter_compress(p_archive);
    //    archive_read_support_filter_gzip(p_archive);
    //    archive_read_support_filter_grzip(p_archive);
    //    archive_read_support_filter_lrzip(p_archive);
    //    archive_read_support_filter_lzip(p_archive);
    archive_read_support_filter_lzma(p_archive);
    archive_read_support_filter_lzop(p_archive);
    archive_read_support_filter_none(p_archive);
    archive_read_support_filter_rpm(p_archive);
    archive_read_support_filter_uu(p_archive);
    archive_read_support_filter_xz(p_archive);

    //    archive_read_support_format_7zip(p_archive);
    archive_read_support_format_ar(p_archive);
    archive_read_support_format_cab(p_archive);
    archive_read_support_format_cpio(p_archive);
    archive_read_support_format_gnutar(p_archive);
    //    archive_read_support_format_iso9660(p_archive);
    archive_read_support_format_lha(p_archive);
    archive_read_support_format_mtree(p_archive);
    archive_read_support_format_rar(p_archive);
    archive_read_support_format_raw(p_archive);
    archive_read_support_format_tar(p_archive);
    archive_read_support_format_xar(p_archive);
    //    archive_read_support_format_zip(p_archive);
}
示例#7
0
文件: nile.c 项目: Gottox/nile
FILE *
uncompress(FILE *f, FILE* out, enum Options options) {
	int fdtmp = -1, i, size;
	struct archive *a = NULL;
	struct archive_entry *entry;
	FILE *rv = f, *ftmp;
	char buf[BUFSIZ], tmpfile[] = "/tmp/nile.XXXXXX", nfilter = 0;

	if(!(options & NILE_DECOMPRESS))
		goto uncompress_cleanup;

	a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_raw(a);
	if(archive_read_open_FILE(a, f) != ARCHIVE_OK ||
	   archive_read_next_header(a, &entry) != ARCHIVE_OK) {
		fprintf(stderr, "Warning: decompression failed while open\n");
		goto uncompress_cleanup;
	}
	if((nfilter = archive_filter_count(a)) == 0) {
		goto uncompress_cleanup;
	}
	if((fdtmp = mkstemp(tmpfile)) == -1) {
		perror("mkstemp");
		goto uncompress_cleanup;
	}

	while((size = archive_read_data(a, buf, sizeof(buf))) > 0) {
		write(fdtmp, buf, size);
	}
	if (size < 0) {
		fprintf(stderr, "Warning: decompression failed read\n");
		goto uncompress_cleanup;
	}
	if((ftmp = fdopen(fdtmp, "r")) == NULL) {
		perror("fdopen");
		goto uncompress_cleanup;
	}
	rv = ftmp;

uncompress_cleanup:
	rewind(f);
	if(out != NULL) {
		for(i = 0; i < nfilter; i++) {
			fputc(archive_filter_code(a, i), out);
		}
		for(i = i % HEADER_PADDING; i < HEADER_PADDING; i++) {
			fputc(0, out);
		}
	}
	if(fdtmp > 0)
		close(fdtmp);
	if(a != NULL) {
		archive_read_free(a);
	}
	return rv;
}
示例#8
0
pu_mtree_reader_t *pu_mtree_reader_open_package( alpm_handle_t *h, alpm_pkg_t *p) {
  pu_mtree_reader_t *reader;
  struct archive *mtree;
  char path[PATH_MAX];
  struct archive_entry *entry = NULL;
  char *buf, rbuf[256];
  size_t len;
  FILE *fbuf;
  const char *dbpath = alpm_option_get_dbpath(h);
  const char *pkgname = alpm_pkg_get_name(p);
  const char *pkgver = alpm_pkg_get_version(p);

  if((fbuf = open_memstream(&buf, &len)) == NULL) { return NULL; }

  sprintf(path, "%slocal/%s-%s/mtree", dbpath, pkgname, pkgver);

  if((mtree = archive_read_new()) == NULL) { return NULL; }
  archive_read_support_filter_all(mtree);
  archive_read_support_format_raw(mtree);
  if(archive_read_open_filename(mtree, path, 64) != ARCHIVE_OK) {
    archive_read_free(mtree);
    return NULL;
  }

  if(archive_read_next_header(mtree, &entry) != ARCHIVE_OK) {
    archive_read_free(mtree);
    return NULL;
  }

  while(1) {
      ssize_t size;
      while((size = archive_read_data(mtree, rbuf, 256)) == ARCHIVE_RETRY);
      if(size < 0) { fclose(fbuf); free(buf); return NULL; }
      if(size == 0) { break; }
      fwrite(rbuf, size, 1, fbuf);
  }
  archive_read_free(mtree);
  fclose(fbuf);

  if((fbuf = fmemopen(buf, len, "r")) == NULL) {
    free(buf);
    return NULL;
  } else if((reader = pu_mtree_reader_open_stream(fbuf)) == NULL) {
    free(buf);
    fclose(fbuf);
    return NULL;
  } else {
    reader->_stream_buf = buf;
    reader->_close_stream = 1;
    return reader;
  }
}
示例#9
0
Reader *Reader::read_open_memory(const char *string, size_t length,
    const char *cmd, bool raw)
{
    struct archive *ar = archive_read_new();

    if (!ar) {
        throw Error("Unable to allocate libarchive handle!");
    }

    char *content = (char*) malloc(length);

    if (!content) {
        archive_read_free(ar);
        throw Error("Unable to allocate memory when duplicating buffer");
    }

    memcpy((void*) content, (void*) string, length);

    try {
        if(cmd) {
            if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_filter_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(raw) {
            if(archive_read_support_format_raw(ar) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_format_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(archive_read_open_memory(ar, (void*) content, length) != ARCHIVE_OK)
            throw 0;

    } catch(...) {
        std::string error_msg = archive_error_string(ar);
        archive_read_free(ar);
        free(content);
        throw Error(error_msg);
    }

    Reader *reader_obj = new Reader(ar);
    reader_obj->_archive_content = content;
    return reader_obj;
}
static void
test_empty_file1(void)
{
	struct archive* a = archive_read_new();

	/* Try opening an empty file with the raw handler. */
	assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	/* Raw handler doesn't support empty files. */
	assertEqualInt(ARCHIVE_FATAL, archive_read_open_filename(a, "emptyfile", 0));
	assert(NULL != archive_error_string(a));

	archive_read_free(a);
}
示例#11
0
static struct archive *open_compressed_file(const char *filename)
{
    struct archive *ar;
    int r;

    ar = archive_read_new();
    if (!ar) {
        opkg_msg(ERROR,
                 "Failed to create archive object for compressed file.\n");
        return NULL;
    }

    /* Support raw data in gzip compression format. */
    r = archive_read_support_filter_gzip(ar);
    if (r == ARCHIVE_WARN) {
        /* libarchive returns ARCHIVE_WARN if the filter is provided by
         * an external program.
         */
        opkg_msg(INFO, "Gzip support provided by external program.\n");
    } else if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Gzip format not supported: %s\n",
                 archive_error_string(ar));
        goto err_cleanup;
    }

    r = archive_read_support_format_raw(ar);
    if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Raw format not supported: %s\n",
                 archive_error_string(ar));
        goto err_cleanup;
    }

    /* Open input file and prepare for reading. */
    r = archive_read_open_filename(ar, filename, EXTRACT_BUFFER_LEN);
    if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Failed to open compressed file '%s': %s\n", filename,
                 archive_error_string(ar));
        goto err_cleanup;
    }

    return ar;

 err_cleanup:
    archive_read_free(ar);
    return NULL;
}
static void
test_empty_file2(void)
{
	struct archive* a = archive_read_new();
	struct archive_entry* e;

	/* Try opening an empty file with raw and empty handlers. */
	assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "emptyfile", 0));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	archive_read_free(a);
}
示例#13
0
struct pkg_vulnerabilities *
read_pkg_vulnerabilities_memory(void *buf, size_t len, int check_sum)
{
#ifdef BOOTSTRAP
	errx(EXIT_FAILURE, "Audit functions are unsupported during bootstrap");
#else
	struct archive *a;
	struct pkg_vulnerabilities *pv;

	if ((a = archive_read_new()) == NULL)
		errx(EXIT_FAILURE, "memory allocation failed");
	
	if (archive_read_support_compression_all(a) != ARCHIVE_OK ||
	    archive_read_support_format_raw(a) != ARCHIVE_OK ||
	    archive_read_open_memory(a, buf, len) != ARCHIVE_OK)
		errx(EXIT_FAILURE, "Cannot open pkg_vulnerabilies buffer: %s",
		    archive_error_string(a));

	pv = read_pkg_vulnerabilities_archive(a, check_sum);

	return pv;
#endif
}
示例#14
0
static void
test_fuzz(const struct files *filesets)
{
	const void *blk;
	size_t blk_size;
	int64_t blk_offset;
	int n;

	for (n = 0; filesets[n].names != NULL; ++n) {
		const size_t buffsize = 30000000;
		struct archive_entry *ae;
		struct archive *a;
		char *rawimage = NULL, *image = NULL, *tmp = NULL;
		size_t size = 0, oldsize = 0;
		int i, q;

		extract_reference_files(filesets[n].names);
		if (filesets[n].uncompress) {
			int r;
			/* Use format_raw to decompress the data. */
			assert((a = archive_read_new()) != NULL);
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_filter_all(a));
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_format_raw(a));
			r = archive_read_open_filenames(a, filesets[n].names, 16384);
			if (r != ARCHIVE_OK) {
				archive_read_free(a);
				if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) {
					skipping("Cannot uncompress fileset");
				} else {
					skipping("Cannot uncompress %s", filesets[n].names[0]);
				}
				continue;
			}
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_next_header(a, &ae));
			rawimage = malloc(buffsize);
			size = archive_read_data(a, rawimage, buffsize);
			assertEqualIntA(a, ARCHIVE_EOF,
			    archive_read_next_header(a, &ae));
			assertEqualInt(ARCHIVE_OK,
			    archive_read_free(a));
			assert(size > 0);
			if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) {
				failure("Internal buffer is not big enough for "
					"uncompressed test files");
			} else {
				failure("Internal buffer is not big enough for "
					"uncompressed test file: %s", filesets[n].names[0]);
			}
			if (!assert(size < buffsize)) {
				free(rawimage);
				continue;
			}
		} else {
			for (i = 0; filesets[n].names[i] != NULL; ++i)
			{
				tmp = slurpfile(&size, filesets[n].names[i]);
				char *newraw = (char *)realloc(rawimage, oldsize + size);
				if (!assert(newraw != NULL))
				{
					free(rawimage);
					continue;
				}
				rawimage = newraw;
				memcpy(rawimage + oldsize, tmp, size);
				oldsize += size;
				size = oldsize;
				free(tmp);
			}
		}
		if (size == 0)
			continue;
		image = malloc(size);
		assert(image != NULL);
		if (image == NULL) {
			free(rawimage);
			return;
		}
		srand((unsigned)time(NULL));

		for (i = 0; i < 1000; ++i) {
			FILE *f;
			int j, numbytes, trycnt;

			/* Fuzz < 1% of the bytes in the archive. */
			memcpy(image, rawimage, size);
			q = (int)size / 100;
			if (q < 4)
				q = 4;
			numbytes = (int)(rand() % q);
			for (j = 0; j < numbytes; ++j)
				image[rand() % size] = (char)rand();

			/* Save the messed-up image to a file.
			 * If we crash, that file will be useful. */
			for (trycnt = 0; trycnt < 3; trycnt++) {
				f = fopen("after.test.failure.send.this.file."
				    "to.libarchive.maintainers.with.system.details", "wb");
				if (f != NULL)
					break;
#if defined(_WIN32) && !defined(__CYGWIN__)
				/*
				 * Sometimes previous close operation does not completely
				 * end at this time. So we should take a wait while
				 * the operation running.
				 */
				Sleep(100);
#endif
			}
			assertEqualInt((size_t)size, fwrite(image, 1, (size_t)size, f));
			fclose(f);

			// Try to read all headers and bodies.
			assert((a = archive_read_new()) != NULL);
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_filter_all(a));
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_format_all(a));

			if (0 == archive_read_open_memory(a, image, size)) {
				while(0 == archive_read_next_header(a, &ae)) {
					while (0 == archive_read_data_block(a,
						&blk, &blk_size, &blk_offset))
						continue;
				}
				archive_read_close(a);
			}
			archive_read_free(a);

			// Just list headers, skip bodies.
			assert((a = archive_read_new()) != NULL);
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_filter_all(a));
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_format_all(a));

			if (0 == archive_read_open_memory(a, image, size)) {
				while(0 == archive_read_next_header(a, &ae)) {
				}
				archive_read_close(a);
			}
			archive_read_free(a);
}
		free(image);
		free(rawimage);
	}
}
示例#15
0
uint8_t *load(void **context,
	      size_t *file_size, FILE *file, size_t max_size)
{
	size_t pos;
	size_t size = 0;
	struct chunk *chunk;
	struct chunk head = { 0, &head, &head };
	size_t chunk_size = load_size(file);
	int error = 0;
#ifdef WITH_LIBARCHIVE
	struct archive *archive = *context;
	struct archive_entry *archive_entry;

	if (archive != NULL)
		goto init_ok;
	archive = archive_read_new();
	*context = archive;
	if (archive == NULL) {
		error = ENOMEM;
		goto error;
	}
	archive_read_support_compression_all(archive);
	archive_read_support_format_all(archive);
	archive_read_support_format_raw(archive);
	if (archive_read_open_FILE(archive, file) != ARCHIVE_OK) {
		error = EIO;
		goto error;
	}
init_ok:
	switch (archive_read_next_header(archive, &archive_entry)) {
	case ARCHIVE_OK:
		break;
	case ARCHIVE_EOF:
		error = 0;
		goto error;
	default:
		error = EIO;
		goto error;
	}
#else
	*context = (void *)0xffff;
#endif
	if (chunk_size == 0)
		chunk_size = CHUNK_SIZE;
	else if ((max_size != 0) && (chunk_size > max_size))
		chunk_size = max_size;
	while (1) {
		pos = 0;
		chunk = malloc(sizeof(*chunk) + chunk_size);
		if (chunk == NULL) {
			error = errno;
			goto error;
		}
		chunk->size = chunk_size;
		chunk->next = &head;
		chunk->prev = head.prev;
		chunk->prev->next = chunk;
		head.prev = chunk;
		do {
			size_t i;
#ifdef WITH_LIBARCHIVE
			ssize_t j;

			j = archive_read_data(archive, &chunk->data[pos],
					      (chunk->size - pos));
			/*
			  Don't bother with ARCHIVE_WARN and ARCHIVE_RETRY,
			  consider any negative value an error.
			*/
			if (j < 0) {
				error = EIO;
				goto error;
			}
			i = (size_t)j;
#else
			i = fread(&chunk->data[pos], 1, (chunk->size - pos),
				  file);
#endif
			if (i == 0) {
				chunk->size = pos;
#ifndef WITH_LIBARCHIVE
				if (ferror(file)) {
					error = EIO;
					goto error;
				}
				assert(feof(file));
#endif
				goto process;
			}
			pos += i;
			size += i;
			if ((max_size != 0) && (size > max_size)) {
				error = EFBIG;
				goto error;
			}
		}
		while (pos != chunk->size);
		chunk_size = CHUNK_SIZE;
	}
process:
	chunk = realloc(head.next, (sizeof(*chunk) + size));
	if (chunk == NULL) {
		error = errno;
		goto error;
	}
	chunk->next->prev = chunk;
	head.next = chunk;
	pos = chunk->size;
	chunk->size = size;
	chunk = chunk->next;
	while (chunk != &head) {
		struct chunk *next = chunk->next;

		memcpy(&head.next->data[pos], chunk->data, chunk->size);
		pos += chunk->size;
		chunk->next->prev = chunk->prev;
		chunk->prev->next = chunk->next;
		free(chunk);
		chunk = next;
	}
	chunk = head.next;
	chunk->prev = chunk;
	chunk->next = chunk;
	if (file_size != NULL)
		*file_size = chunk->size;
	return chunk->data;
error:
#ifdef WITH_LIBARCHIVE
	load_finish(context);
#endif
	chunk = head.next;
	while (chunk != &head) {
		struct chunk *next = chunk->next;

		free(chunk);
		chunk = next;
	}
	errno = error;
	return NULL;
}
示例#16
0
static int
add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
    int mbs, const void *pathname, int nullSeparator)
{
	struct archive *ar;
	struct archive_entry *ae;
	struct archive_string as;
	const void *buff;
	size_t size;
	int64_t offset;
	int r;

	ar = archive_read_new(); 
	if (ar == NULL) {
		archive_set_error(&(a->archive), ENOMEM, "No memory");
		return (ARCHIVE_FATAL);
	}
	r = archive_read_support_format_raw(ar);
	r = archive_read_support_format_empty(ar);
	if (r != ARCHIVE_OK) {
		archive_copy_error(&(a->archive), ar);
		archive_read_free(ar);
		return (r);
	}
	if (mbs)
		r = archive_read_open_filename(ar, pathname, 512*20);
	else
		r = archive_read_open_filename_w(ar, pathname, 512*20);
	if (r != ARCHIVE_OK) {
		archive_copy_error(&(a->archive), ar);
		archive_read_free(ar);
		return (r);
	}
	r = archive_read_next_header(ar, &ae);
	if (r != ARCHIVE_OK) {
		archive_read_free(ar);
		if (r == ARCHIVE_EOF) {
			return (ARCHIVE_OK);
		} else {
			archive_copy_error(&(a->archive), ar);
			return (r);
		}
	}

	archive_string_init(&as);

	while ((r = archive_read_data_block(ar, &buff, &size, &offset))
	    == ARCHIVE_OK) {
		const char *b = (const char *)buff;

		while (size) {
			const char *s = (const char *)b;
			size_t length = 0;
			int found_separator = 0;

			while (length < size) {
				if (nullSeparator) {
					if (*b == '\0') {
						found_separator = 1;
						break;
					}
				} else {
			            	if (*b == 0x0d || *b == 0x0a) {
						found_separator = 1;
						break;
					}
				}
				b++;
				length++;
			}
			if (!found_separator) {
				archive_strncat(&as, s, length);
				/* Read next data block. */
				break;
			}
			b++;
			size -= length + 1;
			archive_strncat(&as, s, length);

			/* If the line is not empty, add the pattern. */
			if (archive_strlen(&as) > 0) {
				/* Add pattern. */
				r = add_pattern_mbs(a, mlist, as.s);
				if (r != ARCHIVE_OK) {
					archive_read_free(ar);
					archive_string_free(&as);
					return (r);
				}
				archive_string_empty(&as);
			}
		}
	}

	/* If an error occurred, report it immediately. */
	if (r < ARCHIVE_OK) {
		archive_copy_error(&(a->archive), ar);
		archive_read_free(ar);
		archive_string_free(&as);
		return (r);
	}

	/* If the line is not empty, add the pattern. */
	if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
		/* Add pattern. */
		r = add_pattern_mbs(a, mlist, as.s);
		if (r != ARCHIVE_OK) {
			archive_read_free(ar);
			archive_string_free(&as);
			return (r);
		}
	}
	archive_read_free(ar);
	archive_string_free(&as);
	return (ARCHIVE_OK);
}
示例#17
0
static void
test_format(int	(*set_format)(struct archive *))
{
	char filedata[64];
	struct archive_entry *ae;
	struct archive *a;
	size_t used;
	size_t buffsize = 1000000;
	char *buff;
	const char *err;

	buff = malloc(buffsize);

	/* Create a new archive in memory. */
	assert((a = archive_write_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));

	/*
	 * Write a file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_set_pathname(ae, "test");
	archive_entry_set_filetype(ae, AE_IFREG);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
	archive_entry_free(ae);
	assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/*
	 * Read from it.
	 */
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualIntA(a, 9, archive_read_data(a, filedata, 10));
	assertEqualMem(filedata, "12345678", 9);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));

	/* Create a new archive */
	assert((a = archive_write_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));

	/* write first file: that should succeed */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_set_pathname(ae, "test");
	archive_entry_set_filetype(ae, AE_IFREG);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
	archive_entry_free(ae);
	assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9));

	/* write second file: this should fail */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_set_pathname(ae, "test2");
	archive_entry_set_filetype(ae, AE_IFREG);
	assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae));
	err = archive_error_string(a);
	assertEqualMem(err, "Raw format only supports one entry per archive", 47);
	archive_entry_free(ae);

	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* Create a new archive */
	assert((a = archive_write_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));

	/* write a directory: this should fail */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, "dir");
	archive_entry_set_filetype(ae, AE_IFDIR);
	archive_entry_set_size(ae, 512);
	assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae));
	err = archive_error_string(a);
	assertEqualMem(err, "Raw format only supports filetype AE_IFREG", 43);
	archive_entry_free(ae);

	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	free(buff);
}