Commit 52d6fcf1de3a5079d208009dcb24937f696c328e

Authored by Jay Berkenbilt
1 parent 52f1721e

Notes on possible safe QPDFObjectHandle

Showing 1 changed file with 57 additions and 0 deletions
... ... @@ -4,6 +4,63 @@ Documentation
4 4 * See #530 -- add an appendix explaining PDF encryption in general
5 5 plus how it's handled by qpdf.
6 6  
  7 +Safer QPDFObjectHandle
  8 +======================
  9 +
  10 +Consider one of the following or something similar to make it possible
  11 +to completely eliminate warnings from treating objects of one type as
  12 +objects of a different type.
  13 +
  14 +Modeled after rust's Option type:
  15 +
  16 +```
  17 +QPDFSafeObjectHandle soh = getObjectFromSomewhere();
  18 +
  19 +// QPDFSafeObjectHandle would be just like QPDFObjectHandle except
  20 +// none of the type-specific methods would be there.
  21 +QPDFDictionaryHandle dh = soh.asDictionary();
  22 +if (dh.isValid()) {
  23 + QPDFSafeObjectHandle value = dh.value().getKey("/Key");
  24 +}
  25 +```
  26 +
  27 +More like typescript's narrowing:
  28 +
  29 +```
  30 +QPDFSafeObjectHandle soh = getObjectFromSomewhere();
  31 +QPDFSafeObjectHandle value = soh.getKey("/Key");
  32 +```
  33 +
  34 +this would raise `std::logic_error` even if soh was a dictionary. But this would work:
  35 +
  36 +```
  37 +QPDFSafeObjectHandle soh = getObjectFromSomewhere();
  38 +if (soh.isDictionary()) {
  39 + QPDFSafeObjectHandle value = soh.getKey("/Key");
  40 +}
  41 +```
  42 +
  43 +In safe mode, we would have checkers (like we do now) but we would
  44 +track whether a specific checker had been called and throw a
  45 +`std::logic_error` if we call a type-specific method without first
  46 +calling a checker. This means that code that passes the happy path
  47 +still has to always do type checks, and this should completely
  48 +eliminate type mismatch warnings.
  49 +
  50 +Migrating existing code to use this safe version would just be a
  51 +matter of changing all occurrences of `QPDFObjectHandle` to
  52 +`QPDFSafeObjectHandle` and making sure you had test coverage on every
  53 +accessor/mutator method call. If you did and the code worked for the
  54 +happy path, then you would be assured of never getting a warning about
  55 +the a method called on an object of the wrong type.
  56 +
  57 +Implementation idea: maybe make a QPDFObjectHandleInternal<bool safe>
  58 +template with QPDFObjectHandle as QPDFObjectHandleInternal<false> and
  59 +QPDFSafeObjectHandle as QPDFObjectHandle<true>. We could then
  60 +potentially specialize certain methods to reduce the overhead and code
  61 +duplication without causing a change to the behavior of any existing
  62 +code.
  63 +
7 64 Document-level work
8 65 ===================
9 66  
... ...