mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
#181 OSS-Fuzz ZBarcode_Encode_File fix, allow for zero-length file, free buffer on error
This commit is contained in:
parent
027e8a775d
commit
0f5deccfb6
@ -1424,13 +1424,14 @@ int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, unsigned char
|
|||||||
int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
|
int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
unsigned long fileLen;
|
long fileLen;
|
||||||
unsigned int nRead = 0, n = 0;
|
size_t n;
|
||||||
|
int nRead = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!strcmp(filename, "-")) {
|
if (!strcmp(filename, "-")) {
|
||||||
file = stdin;
|
file = stdin;
|
||||||
fileLen = 7100;
|
fileLen = 7900;
|
||||||
} else {
|
} else {
|
||||||
file = fopen(filename, "rb");
|
file = fopen(filename, "rb");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -1444,13 +1445,19 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
|
|||||||
fileLen = ftell(file);
|
fileLen = ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
if (fileLen > 7100) {
|
if (fileLen > 7900) {
|
||||||
/* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */
|
/* The largest amount of data that can be encoded is 7827 numeric digits in Han Xin Code */
|
||||||
strcpy(symbol->errtxt, "230: Input file too long");
|
strcpy(symbol->errtxt, "230: Input file too long");
|
||||||
error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
|
error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return ZINT_ERROR_INVALID_DATA;
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
if (fileLen <= 0) {
|
||||||
|
strcpy(symbol->errtxt, "235: Input file empty or unseekable");
|
||||||
|
error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
|
||||||
|
fclose(file);
|
||||||
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
@ -1458,8 +1465,9 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
|
|||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
strcpy(symbol->errtxt, "231: Internal memory error");
|
strcpy(symbol->errtxt, "231: Internal memory error");
|
||||||
error_tag(symbol->errtxt, ZINT_ERROR_MEMORY);
|
error_tag(symbol->errtxt, ZINT_ERROR_MEMORY);
|
||||||
if (strcmp(filename, "-"))
|
if (strcmp(filename, "-")) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
}
|
||||||
return ZINT_ERROR_MEMORY;
|
return ZINT_ERROR_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1469,12 +1477,18 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
|
|||||||
n = fread(buffer + nRead, 1, fileLen - nRead, file);
|
n = fread(buffer + nRead, 1, fileLen - nRead, file);
|
||||||
if (ferror(file)) {
|
if (ferror(file)) {
|
||||||
strcpy(symbol->errtxt, strerror(errno));
|
strcpy(symbol->errtxt, strerror(errno));
|
||||||
|
if (strcmp(filename, "-")) {
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
return ZINT_ERROR_INVALID_DATA;
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
nRead += n;
|
nRead += n;
|
||||||
} while (!feof(file) && (0 < n) && (nRead < fileLen));
|
} while (!feof(file) && (0 < n) && (nRead < fileLen));
|
||||||
|
|
||||||
fclose(file);
|
if (strcmp(filename, "-")) {
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
ret = ZBarcode_Encode(symbol, buffer, nRead);
|
ret = ZBarcode_Encode(symbol, buffer, nRead);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -30,6 +30,9 @@
|
|||||||
/* vim: set ts=4 sw=4 et : */
|
/* vim: set ts=4 sw=4 et : */
|
||||||
|
|
||||||
#include "testcommon.h"
|
#include "testcommon.h"
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
static void test_checks(void)
|
static void test_checks(void)
|
||||||
{
|
{
|
||||||
@ -143,10 +146,64 @@ static void test_input_mode(void)
|
|||||||
testFinish();
|
testFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #181 Nico Gunkel OSS-Fuzz
|
||||||
|
static void test_encode_file_zero_length(void)
|
||||||
|
{
|
||||||
|
testStart("");
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
char filename[] = "in.bin";
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
struct zint_symbol* symbol = ZBarcode_Create();
|
||||||
|
assert_nonnull(symbol, "Symbol not created\n");
|
||||||
|
|
||||||
|
(void)remove(filename); // In case junk hanging around
|
||||||
|
fd = creat(filename, S_IRUSR);
|
||||||
|
assert_nonzero(fd, "Input file not created\n");
|
||||||
|
assert_zero(close(fd), "close(%s) != 0\n", filename);
|
||||||
|
|
||||||
|
ret = ZBarcode_Encode_File(symbol, filename);
|
||||||
|
assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ret %d != ZINT_ERROR_INVALID_DATA\n", ret);
|
||||||
|
|
||||||
|
assert_zero(remove(filename), "remove(%s) != 0\n", filename);
|
||||||
|
|
||||||
|
ZBarcode_Delete(symbol);
|
||||||
|
|
||||||
|
testFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method
|
||||||
|
static void test_encode_file_directory(void)
|
||||||
|
{
|
||||||
|
testStart("");
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
char dirname[] = "in_dir";
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
struct zint_symbol* symbol = ZBarcode_Create();
|
||||||
|
assert_nonnull(symbol, "Symbol not created\n");
|
||||||
|
|
||||||
|
(void)rmdir(dirname); // In case junk hanging around
|
||||||
|
assert_zero(mkdir(dirname, 0700), "mkdir(%s, 0700) != 0\n", dirname);
|
||||||
|
|
||||||
|
ret = ZBarcode_Encode_File(symbol, dirname);
|
||||||
|
assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt);
|
||||||
|
|
||||||
|
assert_zero(rmdir(dirname), "rmdir(%s) != 0\n", dirname);
|
||||||
|
|
||||||
|
ZBarcode_Delete(symbol);
|
||||||
|
|
||||||
|
testFinish();
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_checks();
|
test_checks();
|
||||||
test_input_mode();
|
test_input_mode();
|
||||||
|
test_encode_file_zero_length();
|
||||||
|
test_encode_file_directory();
|
||||||
|
|
||||||
testReport();
|
testReport();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user