Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-4631

NPE due to bounding box not being set on PDAppearanceStream

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.0.16
    • 2.0.17, 3.0.0 PDFBox
    • AcroForm
    • None
    • Windows 10

    Description

      PDFBox 2.0.16 as well as the current SNAPSNOT version crashes with a NullPointerException. Attached is a small test that triggers the NPE, as well as the PDF.

      The stack trace:

      java.lang.NullPointerException
          at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.applyPadding(AppearanceGeneratorHelper.java:816)
          at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.insertGeneratedCombAppearance(AppearanceGeneratorHelper.java:611)
          at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.insertGeneratedAppearance(AppearanceGeneratorHelper.java:505)
          at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceContent(AppearanceGeneratorHelper.java:374)
          at org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceValue(AppearanceGeneratorHelper.java:223)
          at org.apache.pdfbox.pdmodel.interactive.form.PDTextField.constructAppearances(PDTextField.java:264)
          at org.apache.pdfbox.pdmodel.interactive.form.PDTerminalField.applyChange(PDTerminalField.java:228)
          at org.apache.pdfbox.pdmodel.interactive.form.PDTextField.setValue(PDTextField.java:219)
          at PdfBoxTest.reformatFields(PdfBoxTest.java:67)
          at PdfBoxTest.flattenDocument(PdfBoxTest.java:52)
          at PdfBoxTest.flatten(PdfBoxTest.java:42)
          at PdfBoxTest.fileWithStrangeContent(PdfBoxTest.java:27)

       

      The origin of the error seems to be in AppearanceGeneratorHelper.setAppearanceValue(). A PDAppearanceStream is created, but a bounding box is only set for it if this is false: if (appearance != null && appearance.isStream()). In my case, the conditional is true, and PDFBox takes a path where no bounding box gets set.

      The following could be a solution, but I'm not very fluent in the inner workings of PDFs, and it's not directly obvious from looking at the code that this is a good approach.

      
      diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
      index dc2825d4c..a82236069 100644
      --- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
      +++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
      @@ -201,6 +201,7 @@ class AppearanceGeneratorHelper
                       if (appearance != null && appearance.isStream())
                       {
                           appearanceStream = appearance.getAppearanceStream();
      +                    setBoundingBoxOnAppearanceStream(widget, appearanceStream);
                       }
                       else
                       {
      @@ -235,15 +236,9 @@ class AppearanceGeneratorHelper
      
               // Calculate the entries for the bounding box and the transformation matrix
               // settings for the appearance stream
      -        int rotation = resolveRotation(widget);
      -        PDRectangle rect = widget.getRectangle();
      -        Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0);
      -        Point2D.Float point2D = matrix.transformPoint(rect.getWidth(), rect.getHeight());
      +        setBoundingBoxOnAppearanceStream(widget, appearanceStream);
      
      -        PDRectangle bbox = new PDRectangle(Math.abs((float) point2D.getX()), Math.abs((float) point2D.getY()));
      -        appearanceStream.setBBox(bbox);
      -
      -        AffineTransform at = calculateMatrix(bbox, rotation);
      +        AffineTransform at = calculateMatrix(appearanceStream.getBBox(), resolveRotation(widget));
               if (!at.isIdentity())
               {
                   appearanceStream.setMatrix(at);
      @@ -252,7 +247,17 @@ class AppearanceGeneratorHelper
               appearanceStream.setResources(new PDResources());
               return appearanceStream;
           }
      -
      +
      +    private void setBoundingBoxOnAppearanceStream(PDAnnotationWidget widget, PDAppearanceStream appearanceStream) {
      +        int rotation = resolveRotation(widget);
      +        PDRectangle rect = widget.getRectangle();
      +        Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0);
      +        Point2D.Float point2D = matrix.transformPoint(rect.getWidth(), rect.getHeight());
      +
      +        PDRectangle bbox = new PDRectangle(Math.abs((float) point2D.getX()), Math.abs((float) point2D.getY()));
      +        appearanceStream.setBBox(bbox);
      +    }
      +
           private PDDefaultAppearanceString getWidgetDefaultAppearanceString(PDAnnotationWidget widget) throws IOException
           {
               COSString da = (COSString) widget.getCOSObject().getDictionaryObject(COSName.DA);
      

      Attachments

        1. bidragsoknad_strange-content.pdf
          3.25 MB
          sjoblomj
        2. PdfBoxTest.java
          2 kB
          sjoblomj

        Activity

          People

            tilman Tilman Hausherr
            sjoblomj sjoblomj
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: