Source: rst2pdf Version: 0.93-4 Severity: wishlist Tags: patch User: reproducible-bui...@lists.alioth.debian.org Usertags: toolchain randomness X-Debbugs-Cc: reproducible-bui...@lists.alioth.debian.org
Hi, While working on the "reproducible builds" effort [1], we have noticed that rst2pdf can generate PDFs with non-determinstic output. What happens is that because the monkey-patched PDFDate does not extend PDFObject, when Reportlab goes to format it: # reportlab/pdfbase/pdfpattern.py if isinstance(x,strTypes): L.append(pdfdocEnc(x)) elif isinstance(x,PDFObject): L.append(x.format(document)) else: # [..] L.append(pdfdocEnc(str(value))) ... we don't call .format(), but rather we end up calling str(..) on the our monkey-patched instance, returning a value such as: "<rst2pdf.createpdf.PDFDate instance at 0x7fc7cd56b320>" This string gets embedded into the final PDF via the CreationDate PDF metadata and, as the embedded memory address is non-deterministic, it results in non-reproducible output. The attached patch simply specifies PDFObject as the parent class so we take the right branch in the above code. Once applied, various packages can then be built reproducibly in our current experimental framework. [1]: https://wiki.debian.org/ReproducibleBuilds Regards, -- ,''`. : :' : Chris Lamb `. `'` la...@debian.org / chris-lamb.co.uk `-
diff --git a/rst2pdf/createpdf.py b/rst2pdf/createpdf.py index 610a518..b4ea39d 100644 --- a/rst2pdf/createpdf.py +++ b/rst2pdf/createpdf.py @@ -1513,7 +1513,7 @@ def patch_PDFDate(): '''Patch reportlab.pdfdoc.PDFDate so the invariant dates work correctly''' from reportlab.pdfbase import pdfdoc import reportlab - class PDFDate: + class PDFDate(pdfdoc.PDFObject): __PDFObject__ = True # gmt offset now suppported def __init__(self, invariant=True, dateFormatter=None):