Commit c380fb00d8e93f8f489cb7a317c21b970bd54b2a
1 parent
197af341
Update TODO for 4.1.0
Prepare update for TODO for publication since there is useful information there for people looking at the repository.
Showing
1 changed file
with
104 additions
and
1 deletions
TODO
| 1 | 4.1.0 | 1 | 4.1.0 |
| 2 | ===== | 2 | ===== |
| 3 | 3 | ||
| 4 | + * The mingw64 package is broken. It contains a 32-bit version of | ||
| 5 | + libstdc++-6.dll. Fix this and make sure it can never happen | ||
| 6 | + again. Ideally we should test in a sandbox, but failing that, at | ||
| 7 | + least run file on all the dlls to make sure they are of the right | ||
| 8 | + type. | ||
| 9 | + | ||
| 10 | + * Add to documentation, and mention this documentation in | ||
| 11 | + README.maintainer: | ||
| 12 | + | ||
| 13 | + Casting policy. | ||
| 14 | + | ||
| 15 | + The C++ code in qpdf is free of old-style casts except where | ||
| 16 | + unavoidable (e.g. where the old-style cast is in a macro provided | ||
| 17 | + by a third-party header file). When there is a need for a cast, it | ||
| 18 | + is handled, in order of preference by rewriting the code to avoid | ||
| 19 | + the need for a cast, calling const_cast, calling static_cast, | ||
| 20 | + calling reinterpret_cast, or calling some combination of the above. | ||
| 21 | + The casting policy explicitly prohibits casting between sizes for | ||
| 22 | + no purpose other than to quiet a compiler warning when there is no | ||
| 23 | + reasonable chance of a problem resulting. The reason for this | ||
| 24 | + exclusion is that it takes away enabling additional compiler | ||
| 25 | + warnings as a tool for making future improvements to this aspect of | ||
| 26 | + the code and also damages the readability of the code. As a last | ||
| 27 | + resort, a compiler-specific pragma may be used to suppress a | ||
| 28 | + warning that we don't want to fix. Examples may include | ||
| 29 | + suppressing warnings about the use of old-style casts in code that | ||
| 30 | + is shared between C and C++ code. | ||
| 31 | + | ||
| 32 | + There are a few significant areas where casting is common in the qpdf | ||
| 33 | + sources or where casting would be required to quiet higher levels | ||
| 34 | + of compiler warnings but is omitted at present: | ||
| 35 | + | ||
| 36 | + * signed vs. unsigned char. For historical reasons, there are a | ||
| 37 | + lot of places in qpdf's internals that deal with unsigned char, | ||
| 38 | + which means that a lot of casting is required to interoperate | ||
| 39 | + with standard library calls and std::string. In retrospect, | ||
| 40 | + qpdf should have probably used signed char everywhere and just | ||
| 41 | + cast to unsigned char when needed. There are reinterpret_cast | ||
| 42 | + calls to go between char* and unsigned char*, and there are | ||
| 43 | + static_cast calls to go between char and unsigned char. These | ||
| 44 | + should always be safe. | ||
| 45 | + | ||
| 46 | + * non-const unsigned char* used in Pipeline interface. The | ||
| 47 | + pipeline interface has a write() call that uses unsigned char* | ||
| 48 | + without a const qualifier. The main reason for this is to | ||
| 49 | + support pipelines that make calls to third-party libraries, such | ||
| 50 | + as zlib, that don't include const in their interfaces. | ||
| 51 | + Unfortunately, there are many places in the code where it is | ||
| 52 | + desirable to have const char* with pipelines. None of the | ||
| 53 | + pipeline implementations in qpdf currently modify the data | ||
| 54 | + passed to write, and doing so would be counter to the intent of | ||
| 55 | + Pipeline. There are places in the code where const_cast is used | ||
| 56 | + to remove the const-ness of pointers going into Pipelines. This | ||
| 57 | + could be potentially unsafe, but there is adequate testing to | ||
| 58 | + assert that it is safe in qpdf's code. | ||
| 59 | + | ||
| 60 | + * size_t vs. qpdf_offset_t. This is pretty much unavoidable since | ||
| 61 | + offsets are signed types and sizes are unsigned types. Whenever | ||
| 62 | + it is necessary to seek by an amount given by a size_t, it | ||
| 63 | + becomes necessary to mix and match between size_t and | ||
| 64 | + qpdf_offset_t. Additionally, qpdf sometimes treats memory | ||
| 65 | + buffers like files, and those seek interfaces have to be | ||
| 66 | + consistent with file-based input sources. Neither gcc nor MSVC | ||
| 67 | + give warnings for this case by default, but both have warning | ||
| 68 | + flags that can enable this. (MSVC: /W14267 or /W3 (which also | ||
| 69 | + enables some additional warnings that we ignore); gcc: | ||
| 70 | + -Wconversion -Wsign-conversion). This could matter for files | ||
| 71 | + whose sizes are larger than 2^63 bytes, but it is reasonable to | ||
| 72 | + expect that a world where such files are common would also have | ||
| 73 | + larger size_t and qpdf_offset_t types in it. I am not aware of | ||
| 74 | + any cases where 32-bit systems that have size_t smaller than | ||
| 75 | + qpdf_offset_t could run into problems, though I can't | ||
| 76 | + conclusively rule out the possibility. In the event that | ||
| 77 | + someone should produce a file that qpdf can't handle because of | ||
| 78 | + what is suspected to be issues involving the handling of size_t | ||
| 79 | + vs. qpdf_offset_t (such files may behave properly on 64-bit | ||
| 80 | + systems but not on 32-bit systems and may have very large | ||
| 81 | + embedded files or streams, for example), the above mentioned | ||
| 82 | + warning flags could be enabled and all those implicit | ||
| 83 | + conversions could be carefully scrutinized. (I have already | ||
| 84 | + gone through that exercise once in adding support for files > | ||
| 85 | + 4GB in size.) I continue to be commited to supporting large | ||
| 86 | + files on 32-bit systems, but I would not go to any lengths to | ||
| 87 | + support corner cases involving large embedded files or large | ||
| 88 | + streams that work on 64-bit systems but not on 32-bit systems | ||
| 89 | + because of size_t being too small. It is reasonable to assume | ||
| 90 | + that anyone working with such files would be using a 64-bit | ||
| 91 | + system anyway. | ||
| 92 | + | ||
| 93 | + * size_t vs. int. There are some cases where size_t and int or | ||
| 94 | + size_t and unsigned int are used interchangeably. These cases | ||
| 95 | + occur when working with very small amounts of memory, such as | ||
| 96 | + with the bit readers (where we're working with just a few bytes | ||
| 97 | + at a time), some cases of strlen, and a few other cases. I have | ||
| 98 | + scrutinized all of these cases and determined them to be safe, | ||
| 99 | + but there is no mechanism in the code to ensure that new unsafe | ||
| 100 | + conversions between int and size_t aren't introduced short of | ||
| 101 | + good testing and strong awareness of the issues. Again, if any | ||
| 102 | + such bugs are suspected in the future, enable the additional | ||
| 103 | + warning flags and scrutinizing the warnings would be in order. | ||
| 104 | + | ||
| 4 | * New public interfaces have been added. | 105 | * New public interfaces have been added. |
| 5 | 106 | ||
| 6 | 107 | ||
| 7 | General | 108 | General |
| 8 | ======= | 109 | ======= |
| 9 | 110 | ||
| 111 | + * Consider providing a Windows installer for qpdf using NSIS. | ||
| 112 | + | ||
| 10 | * Improve the random number seed to make it more secure so that we | 113 | * Improve the random number seed to make it more secure so that we |
| 11 | have stronger random numbers, particularly when multiple files are | 114 | have stronger random numbers, particularly when multiple files are |
| 12 | generated in the same second. This code may need to be | 115 | generated in the same second. This code may need to be |
| @@ -47,7 +150,7 @@ Index: QPDFWriter.cc | @@ -47,7 +150,7 @@ Index: QPDFWriter.cc | ||
| 47 | { | 150 | { |
| 48 | - pushDiscardFilter(); | 151 | - pushDiscardFilter(); |
| 49 | +// pushDiscardFilter(); | 152 | +// pushDiscardFilter(); |
| 50 | -+ XXX = fopen("/tmp/pass1.pdf", "w"); | 153 | ++ XXX = QUtil::safe_fopen("/tmp/pass1.pdf", "w"); |
| 51 | + pushPipeline(new Pl_StdioFile("pass1", XXX)); | 154 | + pushPipeline(new Pl_StdioFile("pass1", XXX)); |
| 52 | + activatePipelineStack(); | 155 | + activatePipelineStack(); |
| 53 | } | 156 | } |