[ftrandom] Various fixes.
* src/tools/ftrandom/ftrandom.c (GOOD_FONTS_DIR): Provide better default. (error_fraction): Make it of type `double' to work as advertized – this was completely broken. Update all related code. (error_count, fcnt): Make it unsigned to fix compiler warnings. Update all related code. (fontlist): Change `len' member to `long' to fix compiler warnings. (FT_MoveTo, FT_LineTo, FT_ConicTo, FT_CubicTo, abort_test): Tag unused variables. (TestFace, FindFonts, copyfont, do_test): Fix compiler warnings. (ExecuteTest): Ditto. Call `FT_Done_FreeType'. (getErrorCnt): Replace `ceil' with an ordinary cast to `unsigned int'. (usage): Improve output. (main): Fix compiler warnings. * src/tools/ftrandom/README: Updated.
This commit is contained in:
parent
b98dfda392
commit
ca8e98d94a
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
2016-09-03 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[ftrandom] Various fixes.
|
||||||
|
|
||||||
|
* src/tools/ftrandom/ftrandom.c (GOOD_FONTS_DIR): Provide better
|
||||||
|
default.
|
||||||
|
(error_fraction): Make it of type `double' to work as advertized –
|
||||||
|
this was completely broken.
|
||||||
|
Update all related code.
|
||||||
|
(error_count, fcnt): Make it unsigned to fix compiler warnings.
|
||||||
|
Update all related code.
|
||||||
|
(fontlist): Change `len' member to `long' to fix compiler warnings.
|
||||||
|
(FT_MoveTo, FT_LineTo, FT_ConicTo, FT_CubicTo, abort_test): Tag
|
||||||
|
unused variables.
|
||||||
|
(TestFace, FindFonts, copyfont, do_test): Fix compiler warnings.
|
||||||
|
(ExecuteTest): Ditto.
|
||||||
|
Call `FT_Done_FreeType'.
|
||||||
|
(getErrorCnt): Replace `ceil' with an ordinary cast to `unsigned
|
||||||
|
int'.
|
||||||
|
(usage): Improve output.
|
||||||
|
(main): Fix compiler warnings.
|
||||||
|
|
||||||
|
* src/tools/ftrandom/README: Updated.
|
||||||
|
|
||||||
2016-09-03 Werner Lemberg <wl@gnu.org>
|
2016-09-03 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[base] Avoid negative bitmap stroke dimensions (#48985).
|
[base] Avoid negative bitmap stroke dimensions (#48985).
|
||||||
|
|
|
@ -1,48 +1,69 @@
|
||||||
ftrandom
|
ftrandom
|
||||||
--------
|
========
|
||||||
|
|
||||||
This program expects a set of directories containing good fonts, and a set
|
This program expects a set of directories containing good fonts, and a set
|
||||||
of extensions of fonts to be tested. It will randomly pick a font, copy it,
|
of extensions of fonts to be tested. It will randomly pick a font, copy it,
|
||||||
introduce and error and then test it.
|
introduce an error and then test it.
|
||||||
|
|
||||||
The FreeType tests are quite basic:
|
The FreeType tests are quite basic; for each erroneous font ftrandom
|
||||||
|
|
||||||
For each erroneous font it
|
. forks off a new tester,
|
||||||
forks off a new tester;
|
. initializes the library,
|
||||||
initializes the library;
|
. opens each font in the file,
|
||||||
opens each font in the file;
|
. loads each glyph,
|
||||||
loads each glyph;
|
. optionally reviews the contours of the glyph,
|
||||||
(optionally reviewing the contours of the glyph)
|
. optionally rasterizes the glyph, and
|
||||||
(optionally rasterizing)
|
. closes the face.
|
||||||
closes the face.
|
|
||||||
|
|
||||||
If the tester exits with a signal, or takes longer than 20 seconds then
|
If a tester takes longer than 20 seconds, ftrandom saves the erroneous font
|
||||||
ftrandom saves the erroneous font and continues. If the tester exits
|
and continues. If the tester exits normally or with an error, then the
|
||||||
normally or with an error, then the superstructure removes the test font and
|
superstructure removes the test font and continues.
|
||||||
continues.
|
|
||||||
|
|
||||||
Arguments are:
|
|
||||||
|
Command line options
|
||||||
|
--------------------
|
||||||
|
|
||||||
--all Test every font in the directory(ies) no matter
|
--all Test every font in the directory(ies) no matter
|
||||||
what its extension (some CID-keyed fonts have no
|
what its extension.
|
||||||
extension).
|
--check-outlines Call `FT_Outline_Decompose' on each glyph.
|
||||||
--check-outlines Call FT_Outline_Decompose on each glyph.
|
|
||||||
--dir <dir> Append <dir> to the list of directories to search
|
--dir <dir> Append <dir> to the list of directories to search
|
||||||
for good fonts.
|
for good fonts. No recursive search.
|
||||||
--error-count <cnt> Introduce <cnt> single-byte errors into the
|
--error-count <cnt> Introduce <cnt> single-byte errors into the
|
||||||
erroneous fonts.
|
erroneous fonts (default: 1).
|
||||||
--error-fraction <frac> Multiply the file size of the font by <frac> and
|
--error-fraction <frac> Multiply the file size of the font by <frac> and
|
||||||
introduce that many errors into the erroneous
|
introduce that many errors into the erroneous
|
||||||
font file.
|
font file. <frac> should be in the range [0;1]
|
||||||
--ext <ext> Add <ext> to the set of font types tested. Known
|
(default: 0.0).
|
||||||
extensions are `ttf', `otf', `ttc', `cid', `pfb',
|
--ext <ext> Add <ext> to the set of font types tested.
|
||||||
`pfa', `bdf', `pcf', `pfr', `fon', `otb', and
|
|
||||||
`cff'.
|
|
||||||
--help Print out this list of options.
|
--help Print out this list of options.
|
||||||
--nohints Specify FT_LOAD_NO_HINTING when loading glyphs.
|
--nohints Specify FT_LOAD_NO_HINTING when loading glyphs.
|
||||||
--rasterize Call FT_Render_Glyph as well as loading it.
|
--rasterize Call `FT_Render_Glyph' as well as loading it.
|
||||||
--result <dir> This is the directory in which test files are
|
--result <dir> This is the directory in which test files are
|
||||||
placed.
|
placed.
|
||||||
--test <file> Run a single test on a pre-generated testcase.
|
--test <file> Run a single test on a pre-generated testcase.
|
||||||
Done in the current process so it can be debugged
|
This is done in the current process so it can be
|
||||||
more easily.
|
debugged more easily.
|
||||||
|
|
||||||
|
The default font extensions tested by ftrandom are
|
||||||
|
|
||||||
|
.ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff
|
||||||
|
|
||||||
|
The default font directory is controlled by the macro `GOOD_FONTS_DIR' in
|
||||||
|
the source code (and can be thus specified during compilation); its default
|
||||||
|
value is
|
||||||
|
|
||||||
|
/usr/local/share/fonts
|
||||||
|
|
||||||
|
The default result directory is `results' (in the current directory).
|
||||||
|
|
||||||
|
|
||||||
|
Compilation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Two possible solutions.
|
||||||
|
|
||||||
|
. Run ftrandom within a debugging tool like `valgrind' to catch various
|
||||||
|
memory issues.
|
||||||
|
|
||||||
|
. Compile FreeType with sanitizer flags as provided by gcc or clang, for
|
||||||
|
example, then link it with ftrandom.
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <math.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
static int rasterize = false;
|
static int rasterize = false;
|
||||||
static char* results_dir = "results";
|
static char* results_dir = "results";
|
||||||
|
|
||||||
#define GOOD_FONTS_DIR "/home/wl/freetype-testfonts"
|
#define GOOD_FONTS_DIR "/usr/local/share/fonts"
|
||||||
|
|
||||||
static char* default_dir_list[] =
|
static char* default_dir_list[] =
|
||||||
{
|
{
|
||||||
|
@ -81,28 +80,31 @@
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int error_count = 1;
|
static unsigned int error_count = 1;
|
||||||
static int error_fraction = 0;
|
static double error_fraction = 0.0;
|
||||||
|
|
||||||
static FT_F26Dot6 font_size = 12 * 64;
|
static FT_F26Dot6 font_size = 12 * 64;
|
||||||
|
|
||||||
static struct fontlist
|
static struct fontlist
|
||||||
{
|
{
|
||||||
char* name;
|
char* name;
|
||||||
int len;
|
long len;
|
||||||
unsigned int isbinary: 1;
|
unsigned int isbinary: 1;
|
||||||
unsigned int isascii: 1;
|
unsigned int isascii: 1;
|
||||||
unsigned int ishex: 1;
|
unsigned int ishex: 1;
|
||||||
|
|
||||||
} *fontlist;
|
} *fontlist;
|
||||||
|
|
||||||
static int fcnt;
|
static unsigned int fcnt;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
FT_MoveTo( const FT_Vector *to,
|
FT_MoveTo( const FT_Vector *to,
|
||||||
void *user )
|
void *user )
|
||||||
{
|
{
|
||||||
|
FT_UNUSED( to );
|
||||||
|
FT_UNUSED( user );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +113,9 @@
|
||||||
FT_LineTo( const FT_Vector *to,
|
FT_LineTo( const FT_Vector *to,
|
||||||
void *user )
|
void *user )
|
||||||
{
|
{
|
||||||
|
FT_UNUSED( to );
|
||||||
|
FT_UNUSED( user );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +125,10 @@
|
||||||
const FT_Vector *to,
|
const FT_Vector *to,
|
||||||
void *user )
|
void *user )
|
||||||
{
|
{
|
||||||
|
FT_UNUSED( _cp );
|
||||||
|
FT_UNUSED( to );
|
||||||
|
FT_UNUSED( user );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +139,11 @@
|
||||||
const FT_Vector *to,
|
const FT_Vector *to,
|
||||||
void *user )
|
void *user )
|
||||||
{
|
{
|
||||||
|
FT_UNUSED( cp1 );
|
||||||
|
FT_UNUSED( cp2 );
|
||||||
|
FT_UNUSED( to );
|
||||||
|
FT_UNUSED( user );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +161,8 @@
|
||||||
static void
|
static void
|
||||||
TestFace( FT_Face face )
|
TestFace( FT_Face face )
|
||||||
{
|
{
|
||||||
int gid;
|
unsigned int gid;
|
||||||
int load_flags = FT_LOAD_DEFAULT;
|
int load_flags = FT_LOAD_DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
if ( check_outlines &&
|
if ( check_outlines &&
|
||||||
|
@ -202,7 +216,7 @@
|
||||||
TestFace( face );
|
TestFace( face );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i, num;
|
long i, num;
|
||||||
|
|
||||||
|
|
||||||
num = face->num_faces;
|
num = face->num_faces;
|
||||||
|
@ -215,6 +229,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_Done_FreeType( context );
|
||||||
|
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,9 +345,10 @@
|
||||||
FindFonts( char** fontdirs,
|
FindFonts( char** fontdirs,
|
||||||
char** extensions )
|
char** extensions )
|
||||||
{
|
{
|
||||||
int i, max;
|
int i;
|
||||||
char buffer[1025];
|
unsigned int max;
|
||||||
struct stat statb;
|
char buffer[1025];
|
||||||
|
struct stat statb;
|
||||||
|
|
||||||
|
|
||||||
max = 0;
|
max = 0;
|
||||||
|
@ -392,13 +409,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static unsigned int
|
||||||
getErrorCnt( struct fontlist* item )
|
getErrorCnt( struct fontlist* item )
|
||||||
{
|
{
|
||||||
if ( error_count == 0 && error_fraction == 0 )
|
if ( error_count == 0 && error_fraction == 0.0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return error_count + ceil( error_fraction * item->len );
|
return error_count + (unsigned int)( error_fraction * item->len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,10 +434,10 @@
|
||||||
copyfont( struct fontlist* item,
|
copyfont( struct fontlist* item,
|
||||||
char* newfont )
|
char* newfont )
|
||||||
{
|
{
|
||||||
static char buffer[8096];
|
static char buffer[8096];
|
||||||
FILE *good, *new;
|
FILE *good, *new;
|
||||||
int len;
|
size_t len;
|
||||||
int i, err_cnt;
|
unsigned int i, err_cnt;
|
||||||
|
|
||||||
|
|
||||||
good = fopen( item->name, "r" );
|
good = fopen( item->name, "r" );
|
||||||
|
@ -446,7 +463,7 @@
|
||||||
err_cnt = getErrorCnt( item );
|
err_cnt = getErrorCnt( item );
|
||||||
for ( i = 0; i < err_cnt; ++i )
|
for ( i = 0; i < err_cnt; ++i )
|
||||||
{
|
{
|
||||||
fseek( new, getRandom( 0, item->len - 1 ), SEEK_SET );
|
fseek( new, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET );
|
||||||
|
|
||||||
if ( item->isbinary )
|
if ( item->isbinary )
|
||||||
putc( getRandom( 0, 0xFF ), new );
|
putc( getRandom( 0, 0xFF ), new );
|
||||||
|
@ -484,6 +501,8 @@
|
||||||
static void
|
static void
|
||||||
abort_test( int sig )
|
abort_test( int sig )
|
||||||
{
|
{
|
||||||
|
FT_UNUSED( sig );
|
||||||
|
|
||||||
/* If a time-out happens, then kill the child */
|
/* If a time-out happens, then kill the child */
|
||||||
kill( child_pid, SIGFPE );
|
kill( child_pid, SIGFPE );
|
||||||
write( 2, "Timeout... ", 11 );
|
write( 2, "Timeout... ", 11 );
|
||||||
|
@ -493,7 +512,7 @@
|
||||||
static void
|
static void
|
||||||
do_test( void )
|
do_test( void )
|
||||||
{
|
{
|
||||||
int i = getRandom( 0, fcnt - 1 );
|
int i = getRandom( 0, (int)( fcnt - 1 ) );
|
||||||
static int test_num = 0;
|
static int test_num = 0;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
|
@ -534,22 +553,42 @@
|
||||||
usage( FILE* out,
|
usage( FILE* out,
|
||||||
char* name )
|
char* name )
|
||||||
{
|
{
|
||||||
|
char** d = default_dir_list;
|
||||||
|
char** e = default_ext_list;
|
||||||
|
|
||||||
|
|
||||||
fprintf( out, "%s [options] -- Generate random erroneous fonts\n"
|
fprintf( out, "%s [options] -- Generate random erroneous fonts\n"
|
||||||
" and attempt to parse them with FreeType.\n\n", name );
|
" and attempt to parse them with FreeType.\n\n", name );
|
||||||
|
|
||||||
fprintf( out, " --all All non-directory files are assumed to be fonts.\n" );
|
fprintf( out, " --all All non-directory files are assumed to be fonts.\n" );
|
||||||
fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" );
|
fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" );
|
||||||
fprintf( out, " --dir <path> Append <path> to list of font search directories.\n" );
|
fprintf( out, " --dir <path> Append <path> to list of font search directories\n"
|
||||||
fprintf( out, " --error-count <cnt> Introduce <cnt> single byte errors into each font.\n" );
|
" (no recursive search).\n" );
|
||||||
|
fprintf( out, " --error-count <cnt> Introduce <cnt> single byte errors into each font\n"
|
||||||
|
" (default: 1)\n" );
|
||||||
fprintf( out, " --error-fraction <frac> Introduce <frac>*filesize single byte errors\n"
|
fprintf( out, " --error-fraction <frac> Introduce <frac>*filesize single byte errors\n"
|
||||||
" into each font.\n" );
|
" into each font (default: 0.0).\n" );
|
||||||
fprintf( out, " --ext <ext> Add <ext> to list of extensions indicating fonts.\n" );
|
fprintf( out, " --ext <ext> Add <ext> to list of extensions indicating fonts.\n" );
|
||||||
fprintf( out, " --help Print this.\n" );
|
fprintf( out, " --help Print this.\n" );
|
||||||
fprintf( out, " --nohints Turn off hinting.\n" );
|
fprintf( out, " --nohints Turn off hinting.\n" );
|
||||||
fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" );
|
fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" );
|
||||||
fprintf( out, " --results <dir> Directory in which to place the test fonts.\n" );
|
fprintf( out, " --results <path> Place the created test fonts into <path>\n"
|
||||||
|
" (default: `results')\n" );
|
||||||
fprintf( out, " --size <float> Use the given font size for the tests.\n" );
|
fprintf( out, " --size <float> Use the given font size for the tests.\n" );
|
||||||
fprintf( out, " --test <file> Run a single test on an already existing file.\n" );
|
fprintf( out, " --test <file> Run a single test on an already existing file.\n" );
|
||||||
|
fprintf( out, "\n" );
|
||||||
|
|
||||||
|
fprintf( out, "Default font extensions:\n" );
|
||||||
|
fprintf( out, " " );
|
||||||
|
while ( *e )
|
||||||
|
fprintf( out, " .%s", *e++ );
|
||||||
|
fprintf( out, "\n" );
|
||||||
|
|
||||||
|
fprintf( out, "Default font directories:\n" );
|
||||||
|
fprintf( out, " " );
|
||||||
|
while ( *d )
|
||||||
|
fprintf( out, " %s", *d++ );
|
||||||
|
fprintf( out, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -564,8 +603,8 @@
|
||||||
char* testfile = NULL;
|
char* testfile = NULL;
|
||||||
|
|
||||||
|
|
||||||
dirs = calloc( argc + 1, sizeof ( char ** ) );
|
dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) );
|
||||||
exts = calloc( argc + 1, sizeof ( char ** ) );
|
exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) );
|
||||||
|
|
||||||
for ( i = 1; i < argc; ++i )
|
for ( i = 1; i < argc; ++i )
|
||||||
{
|
{
|
||||||
|
@ -585,9 +624,9 @@
|
||||||
else if ( strcmp( pt, "-error-count" ) == 0 )
|
else if ( strcmp( pt, "-error-count" ) == 0 )
|
||||||
{
|
{
|
||||||
if ( !rset )
|
if ( !rset )
|
||||||
error_fraction = 0;
|
error_fraction = 0.0;
|
||||||
rset = true;
|
rset = true;
|
||||||
error_count = strtol( argv[++i], &end, 10 );
|
error_count = (unsigned int)strtoul( argv[++i], &end, 10 );
|
||||||
if ( *end != '\0' )
|
if ( *end != '\0' )
|
||||||
{
|
{
|
||||||
fprintf( stderr, "Bad value for error-count: %s\n", argv[i] );
|
fprintf( stderr, "Bad value for error-count: %s\n", argv[i] );
|
||||||
|
@ -605,6 +644,11 @@
|
||||||
fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] );
|
fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
if ( error_fraction < 0.0 || error_fraction > 1.0 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "error-fraction must be in the range [0;1]\n" );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( strcmp( pt, "-ext" ) == 0 )
|
else if ( strcmp( pt, "-ext" ) == 0 )
|
||||||
exts[ecnt++] = argv[++i];
|
exts[ecnt++] = argv[++i];
|
||||||
|
@ -658,7 +702,7 @@
|
||||||
ExecuteTest( testfile ); /* This should never return */
|
ExecuteTest( testfile ); /* This should never return */
|
||||||
|
|
||||||
time( &now );
|
time( &now );
|
||||||
srandom( now );
|
srandom( (unsigned int)now );
|
||||||
|
|
||||||
FindFonts( dirs, exts );
|
FindFonts( dirs, exts );
|
||||||
mkdir( results_dir, 0755 );
|
mkdir( results_dir, 0755 );
|
||||||
|
|
Loading…
Reference in New Issue