Warn for PDF's with compression + unsup'd filters

As described in issue #1721, some PDF's will crash FontForge due to the
use of added filters in combination with object stream compression.

In the example crash, FlateDecode compression was combined with PNG value
filtering,
>   /Filter /FlateDecode
>   <</DecodeParms<</Columns 5/Predictor 12>>

FontForge did not look for nor handle the /DecodeParms value for any
objects.  This basically meant that the object stream was corrupted
and unguarded code used the resulting bad values causing the crash.

Filter implementation would require adding a step after decompression
to un-filter the stream.  There are a number of known filters.  (see
PDF version 1.7 document section 3.3 "Filters" for more details)

As implementation would take time and sample PDF files not available
at present, for now just warn the user that this PDF file contains
features not supported and don't use the file (preventing crash).

The warning as seen from the UI, in "Warnings" popup:
> Unsupported decode filter parameters : <</Columns 5/Predictor 12>>

There may be other warning/error messages, depending on what data part
of the PDF file is found to have this unsupported combination.

Note that this change's check for the problem situation is rather
superficial.  FontForge can be forced to handle subdictionary values
but it is very painful.  Better would be to completely unpack the
/DecodeParms subdictionary and verify that the Predictor value is
not '1'. As it is we only check if /DecodeParms is present and then
give up and warn.
parsepdf.c FindXref() small bug finding startxref

While examining code in parsepdf.c I was confused by code in routine
FindXref() that locates the section in a PDF file that points to the
start of the tables in a PDF. Checking more closely and comparing with
the previous version of the routine, I realized it could be tripped up
by slightly malformed trailers, e.g.
>     endobj
>     sstartxref
>     2250179
>     %%EOF

At first I reworked the code, fusing new code with old to correct the
glitch. But then I realized the code using loops was confusing without
needing to be in order to work.  Replaced loops with straightforward
reading of needed algorithm.

Tested with both good and multiple constructed 'bad' PDF file trailers.

This problem has not actually been demonstrated to my knowledge.
Hitting the bug would have produced messages like:
> Doesn't look like a valid pdf file, couldn't find xref section
> Couldn't find a font file named /home/tom/study/fonts/FF/gdb.pdf.test.3.pdf
> gdb.pdf.test.3.pdf is not in a known format (or uses features of that format fontforge does not support, or is so badly corrupted as to be unreadable)
Merge pull request #1727 from tshinnic/parsepdf_bugs_1

Fix crash in parsepdf.c on filter&compression; fix another minor nit
Fix a problem with the glyph contents omitting the file suffix in the glif name.
Merge pull request #1730 from fontforge/ufo_contents_glif_fix_1

Keep the file name suffix in the glyph contents file in U. F. O..
Coverity lead parsepdf.c pdf_loadtype3()

In routine pdf_loadtype3() variable 'name' was being used by copy()
before being checked for non-NULL.  Moved copy() inside existing
if(name!=NULL) check.

Variable 'enc' was not actually being used (see inline comment) and yet
was being copy()'d and not being freed on error.  Removed the copy() and
existing free().  Also moved the last check for failure higher, before
where the copy() was, which would also have cured the problem.

Fixes
  CID 1083100 (#1 of 1): Resource leak (RESOURCE_LEAK)
  11. leaked_storage: Variable name going out of scope leaks the storage it points to.
  CID 1083112 (#1 of 1): Resource leak (RESOURCE_LEAK)
  11. leaked_storage: Variable enc going out of scope leaks the storage it points to.
Tested with type 3 pdf created by FontForge.
Coverity parsepdf.c toknames[] PDF parsing bug!

Coverity for the win!

Coverity pointed out a typo affecting the contents of an array used when
parsing PDF drawing commands. Astonishingly, the interpretation of some
less-used PDF commands has been wrong since 'forever'.

If there have ever been problems with processing 'some' PDFs, including
PDFs generated by FontForge (!), this bug could have contributed.

An array toknames[] is used to lookup drawing command names.  Indexes
within this table are correlated with the enum constants pstoks.

The typo meant that two name strings, which were intended to be the
separate commands
>   B   Fill and stroke the path (non-zero winding rule)
>   B*  Fill and stroke the path (even-odd winding rule)
were accidentally concatenated as "BB*", and so occupied only one slot
in the table.  This not only meant these two commands were not recognized,
but that every command after that in the table was assigned the *wrong*
enum value.  Such that we had wonderful nonsense like
>       "false"  ==  pt_true

It appears that the table was sorted so that the most frequently seen
commands occurred earlier in the table.  This is the only way that 'enough'
parsing worked so that the bug was not forced to the surface.

Reported as
> CID 1225991 (#1 of 1): Missing comma in a string array initialization (MISSING_COMMA)
> missing_comma: In the initialization of toknames, a suspicious concatenated string "BB*" is produced.

Tested with FontForge-generated PDFs, which happen to contain a command
'D1', which was one of those affected.  Previously matched as index 23 ==
pt_paintnoop it is now correctly matched as index 24 == pt_setcachedevice

Also the dumped table toknames[] previously showed
>       "f*",   "BB*",  "b",
and now shows
>       "f*",   "B",    "B*",
>       "b",    "b*",   "n",
Coverity parsepdf.c/psread.c fix uninitilized member

Low-priority minor change to explicitly initialize one member of
struct pskeydict (defined in fontforge/sd.h)

Coverity CID's 1082745 and 1082719 were complaining
>   CID 1082745 (#1 of 1): Uninitialized scalar variable (UNINIT)
>   42. uninit_use: Using uninitialized value dict. Field dict.is_executable is uninitialized.

This has not been *observed* to create problems, but technically the
flag would likely always be true, influencing subsequent code.

Tested with a couple PDF and .ps files with no apparent changes.
Coverity parsepdf.c FindObjects() tainted/untrusted values

Coverity found that values read from external data sources were not
checked for 'goodness'.  More specifically the upper/lower bounds were
not being checked.

Since a somewhat similar scenario passing through this area crashed
FontForge with bogus values, it seems reasonable to satisfy Coverity
and protect ourselves from this (unlikely) danger.

The starting object number and count of objects is read into variables
'start' and 'num' and used to populate a dynamically allocated array.
Protect against trouble by requiring that start and num are positive
integers less than a (very high) upper bound.  Also that the sum of
those is less than that same bound.  (bound derived as highest observed
object number rounded up to power of 10 and again multipled by 10)

The inserted code protects against values from both fscanf() calls at
top and bottom of routine FindObjects().

The Coverity reports were:
>  CID 1083582: Untrusted value as argument (TAINTED_SCALAR) [select issue]
>  6. overflow: Multiply operation overflows on operands start + num + 1L and 8UL. Example value for operand: start + num + 1L = 4611686018427387904.
>  CID 1083582 (#1 of 7): Untrusted loop bound (TAINTED_SCALAR)
>  8. tainted_data: Using tainted variable start + num as a loop boundary.

Tested against PDF files with the 'xref' table, including the tutorial
file doc/html/fontforge-tutorial.pdf
Coverity parsepdf.c address various reports

A mix of minor fixes against Coverity report items.  All of these
are for code in fontforge/parsepdf.c

=== Routine pdf_loadfont()    line ~ 1933
CID 1226268 (#1 of 1): Dereference null return value (NULL_RETURNS)

Coverity reported that a returned pointer could be NULL, but that error
return value wasn't being handled by calling code in pdf_loadfont().

Unlikely to happen (tmpfile() failing?) but I checked that pdf_loadfont()
callers could handle error return of NULL, and saw example use just above
area, so added guard against return of NULL from _ReadPSFont().

Coverity report was
>  CID 1226268 (#1 of 1): Dereference null return value (NULL_RETURNS)
>  15. dereference: Dereferencing a pointer that might be null fd when calling SplineFontFromPSFont. [show details]
>      1956        fd = _ReadPSFont(file);

Tested against PDF containing type 1 font ("/FontFile") both with and
without forcing the returned value to NULL.

=== Routine pdf_getinteger()   line ~ 636

Coverity complained that the return value from ftell() was being used
with fseek() without first checking for the error return value -1.
Added an "if(here<0) return(0)" emulating the several other error
returns in the routine pdf_getinteger().

Coverity report was
>  CID 1083667 (#1 of 1): Argument cannot be negative (NEGATIVE_RETURNS)
>  11. negative_returns: here is passed to a parameter that cannot be negative.
>       648    fseek(pc->pdf,here,SEEK_SET);

Could not test definitively as no available PDF had data that passed
through this code path.

=== Routine pdf_getcmap()   line ~ 1749

Coverity complained that the string variable 'prevtok' was being used
before being initialized, which was very true. Later in the code variable
'tok' would be copied into it, but no initial value was set.  The
surrounding code made mistakes unlikely but...

Coverity report was
>  CID 1225176 (#2 of 2): Uninitialized scalar variable (UNINIT)
>  8. uninit_use_in_call: Using uninitialized element of array prevtok when calling sscanf.

Tested with PDF having CMap and verified 'prevtok' was uninitialized,
and initialized after code change.
>   char tok[200], *ccval, prevtok[200];
>   char tok[200], *ccval, prevtok[200]="";

Coverity complained that dynamic calloc() into 'mappings' was not being
released, which was true.

Coverity report was
>  CID 1083111 (#4-1 of 5): Resource leak (RESOURCE_LEAK)
>  50. leaked_storage: Variable mappings going out of scope leaks the storage it points to.

Tested with PDF having CMap.

=== Routine pdf_findfonts()   line ~ 556

Coverity complained about an allocation leak.  Code needed to make a copy
of a transient value 'pt' (the font name) as a following call would erase
the value. But then the copy was only used inside a conditional, and if
false then no one released the memory.

Coverity report was
>  CID 1083101 (#2 of 3): Resource leak (RESOURCE_LEAK)
>  73. leaked_storage: Variable tpt going out of scope leaks the storage it points to.

Tested the true path (and found I'd coded it wrong and fixed to this
version).  Haven't found a PDF passing through the false path.

=== Routine add_mapping()    line ~ 1687

Coverity complained about an allocation leak.  Code works very hard to
create a name of many parts, but then only uses that within a conditional.
The memory was not released if the conditional was false.

Coverity report was
>  CID 1083105 (#1-2 of 3): Resource leak (RESOURCE_LEAK)
>  13. leaked_storage: Variable name going out of scope leaks the storage it points to.

Tested the true path, but not able to find a PDF that tests the false path.

=== Routine pdf_readdict()   line ~ 385

Coverity complained about a memory leak.  A copy of a string was being
made to save in a data structure, but that assignment was inside a
conditional.  The memory would be lost if the conditional went the
other way.

Coverity report was
>  CID 1083585 (#1 of 2): Resource leak (RESOURCE_LEAK)
>  16. leaked_storage: Variable value going out of scope leaks the storage it points to.

Tested with various PDFs, as all would pass through this routine.
Merge pull request #1732 from tshinnic/coverity_reports_parsepdf_1

Fixes for Coverity-reported issues: fontforge/parsepdf.c