mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 00:08:50 -05:00
archive_fgets(): ensure we return any trailing text with no newline
Discovered this when doing some pactest rewrite work to generate archives in memory only. If a sync database file or PKGINFO file is missing a newline on the final line, the text from that line gets tossed aside and never read into the package struct. This is pretty critical when that last line is a depend or something. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
1187edb38c
commit
719e0d3ddb
@ -760,9 +760,8 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)
|
|||||||
&b->block_size, &offset);
|
&b->block_size, &offset);
|
||||||
b->block_offset = b->block;
|
b->block_offset = b->block;
|
||||||
|
|
||||||
/* error or end of archive with no data read, cleanup */
|
/* error, cleanup */
|
||||||
if(b->ret < ARCHIVE_OK ||
|
if(b->ret < ARCHIVE_OK) {
|
||||||
(b->block_size == 0 && b->ret == ARCHIVE_EOF)) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -779,19 +778,20 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)
|
|||||||
/* allocate our buffer, or ensure our existing one is big enough */
|
/* allocate our buffer, or ensure our existing one is big enough */
|
||||||
if(!b->line) {
|
if(!b->line) {
|
||||||
/* set the initial buffer to the read block_size */
|
/* set the initial buffer to the read block_size */
|
||||||
CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM);
|
CALLOC(b->line, b->block_size + 1, sizeof(char), b->ret = -ENOMEM; goto cleanup);
|
||||||
b->line_size = b->block_size + 1;
|
b->line_size = b->block_size + 1;
|
||||||
b->line_offset = b->line;
|
b->line_offset = b->line;
|
||||||
} else {
|
} else {
|
||||||
size_t needed = (size_t)((b->line_offset - b->line)
|
size_t needed = (size_t)((b->line_offset - b->line)
|
||||||
+ (i - b->block_offset) + 1);
|
+ (i - b->block_offset) + 1);
|
||||||
if(needed > b->max_line_size) {
|
if(needed > b->max_line_size) {
|
||||||
return ERANGE;
|
b->ret = -ERANGE;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if(needed > b->line_size) {
|
if(needed > b->line_size) {
|
||||||
/* need to realloc + copy data to fit total length */
|
/* need to realloc + copy data to fit total length */
|
||||||
char *new;
|
char *new;
|
||||||
CALLOC(new, needed, sizeof(char), return ENOMEM);
|
CALLOC(new, needed, sizeof(char), b->ret = -ENOMEM; goto cleanup);
|
||||||
memcpy(new, b->line, b->line_size);
|
memcpy(new, b->line, b->line_size);
|
||||||
b->line_size = needed;
|
b->line_size = needed;
|
||||||
b->line_offset = new + (b->line_offset - b->line);
|
b->line_offset = new + (b->line_offset - b->line);
|
||||||
@ -813,6 +813,12 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)
|
|||||||
memcpy(b->line_offset, b->block_offset, len);
|
memcpy(b->line_offset, b->block_offset, len);
|
||||||
b->line_offset += len;
|
b->line_offset += len;
|
||||||
b->block_offset = i;
|
b->block_offset = i;
|
||||||
|
/* there was no new data, return what is left; saved ARCHIVE_EOF will be
|
||||||
|
* returned on next call */
|
||||||
|
if(len == 0) {
|
||||||
|
b->line_offset[0] = '\0';
|
||||||
|
return ARCHIVE_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user