使用 Apache PDFBox 在 PDF 中查找 javascript 代码

2023-12-19

我的目标是提取和处理 PDF 文档可能包含的任何 JavasCript 代码。通过在编辑器中打开 PDF,我可以看到如下对象:

    402 0 obj
<</S/JavaScript/JS(\n\r\n   /* Set day 25 */\r\n    FormRouter_SetCurrentDate\("25"\);\r)>>
endobj

我正在尝试使用 Apache PDFBox 来完成此任务,但到目前为止还没有成功。

此行返回一个空列表:

 jsObj = doc.getObjectsByType(COSName.JAVA_SCRIPT);

谁能给我一些指导吗?


该工具基于 PDFBox 中的 PrintFields 示例。它将在表单中显示 Javascript 字段。我去年为一个在 AcroForm 字段之间的关系方面遇到问题的人写了这篇文章(某些字段根据其他字段的值启用/禁用)。还有其他地方可以使用 Javascript。

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package pdfboxpageimageextraction;

import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDNonTerminalField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTerminalField;

/**
 * This example will take a PDF document and print all the fields from the file.
 *
 * @author Ben Litchfield
 *
 */
public class PrintJavaScriptFields
{

    /**
     * This will print all the fields from the document.
     *
     * @param pdfDocument The PDF to get the fields from.
     *
     * @throws IOException If there is an error getting the fields.
     */
    public void printFields(PDDocument pdfDocument) throws IOException
    {
        PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
        PDAcroForm acroForm = docCatalog.getAcroForm();
        List<PDField> fields = acroForm.getFields();

        //System.out.println(fields.size() + " top-level fields were found on the form");
        for (PDField field : fields)
        {
            processField(field, "|--", field.getPartialName());
        }
    }

    private void processField(PDField field, String sLevel, String sParent) throws IOException
    {
        String partialName = field.getPartialName();

        if (field instanceof PDTerminalField)
        {
            PDTerminalField termField = (PDTerminalField) field;
            PDFormFieldAdditionalActions fieldActions = field.getActions();
            if (fieldActions != null)
            {
                System.out.println(field.getFullyQualifiedName() + ": " + fieldActions.getClass().getSimpleName() + " js field actionS:\n" + fieldActions.getCOSObject());
                printPossibleJS(fieldActions.getK());
                printPossibleJS(fieldActions.getC());
                printPossibleJS(fieldActions.getF());
                printPossibleJS(fieldActions.getV());
            }
            for (PDAnnotationWidget widgetAction : termField.getWidgets())
            {
                PDAction action = widgetAction.getAction();
                if (action instanceof PDActionJavaScript)
                {
                    System.out.println(field.getFullyQualifiedName() + ": " + action.getClass().getSimpleName() + " js widget action:\n" + action.getCOSObject());
                    printPossibleJS(action);
                }
            }
        }

        if (field instanceof PDNonTerminalField)
        {
            if (!sParent.equals(field.getPartialName()))
            {
                if (partialName != null)
                {
                    sParent = sParent + "." + partialName;
                }
            }
            //System.out.println(sLevel + sParent);

            for (PDField child : ((PDNonTerminalField) field).getChildren())
            {
                processField(child, "|  " + sLevel, sParent);
            }
        }
        else
        {
            String fieldValue = field.getValueAsString();
            StringBuilder outputString = new StringBuilder(sLevel);
            outputString.append(sParent);
            if (partialName != null)
            {
                outputString.append(".").append(partialName);
            }
            outputString.append(" = ").append(fieldValue);
            outputString.append(", type=").append(field.getClass().getName());
            //System.out.println(outputString);
        }
    }

    private void printPossibleJS(PDAction kAction)
    {
        if (kAction instanceof PDActionJavaScript)
        {
            PDActionJavaScript jsAction = (PDActionJavaScript) kAction;
            String jsString = jsAction.getAction();
            if (!jsString.contains("\n"))
            {
                // avoid display problems with netbeans
                jsString = jsString.replaceAll("\r", "\n").replaceAll("\n\n", "\n");
            }
            System.out.println(jsString);
            System.out.println();
        }
    }

    /**
     * This will read a PDF file and print out the form elements. <br />
     * see usage() for commandline
     *
     * @param args command line arguments
     *
     * @throws IOException If there is an error importing the FDF document.
     */
    public static void main(String[] args) throws IOException
    {
        PDDocument pdf = null;
        try
        {
            pdf = PDDocument.load(new File("XXXX", "YYYYY.pdf"));
            PrintJavaScriptFields exporter = new PrintJavaScriptFields();
            exporter.printFields(pdf);
        }
        finally
        {
            if (pdf != null)
            {
                pdf.close();
            }
        }
    }

} 

作为奖励,下面是显示所有 COSString 对象的代码:

public class ShowAllCOSStrings
{
    static Set<COSString> strings = new HashSet<COSString>();

    static void crawl(COSBase base)
    {
        if (base instanceof COSString)
        {
            strings.add((COSString)base);
            return;
        }
        if (base instanceof COSDictionary)
        {
            COSDictionary dict = (COSDictionary) base;
            for (COSName key : dict.keySet())
            {
                crawl(dict.getDictionaryObject(key));
            }
            return;
        }
        if (base instanceof COSArray)
        {
            COSArray ar = (COSArray) base;

            for (COSBase item : ar)
            {
                crawl(item);
            }
            return;
        }
        if (base instanceof COSNull || 
                base instanceof COSObject || 
                base instanceof COSName || 
                base instanceof COSNumber || 
                base instanceof COSBoolean || 
                base == null)
        {
            return;
        }
        System.out.println("huh? " + base);
    }

    public static void main(String[] args) throws IOException
    {
        PDDocument doc = PDDocument.load(new File("XXX","YYY.pdf"));

        for (COSObject obj : doc.getDocument().getObjects())
        {
            COSBase base = obj.getObject();
            //System.out.println(obj + ": " + base);
            crawl(base);
        }
        System.out.println(strings.size() + " strings:");
        for (COSString s : strings)
        {
            String str = s.getString();
            if (!str.contains("\n"))
            {
                // avoid display problems with netbeans
                str = str.replaceAll("\r", "\n").replaceAll("\n\n", "\n");
            }
            System.out.println(str);
        }
        doc.close();
    }
}

然而 Javascript 也可以在流中。请参阅 PDF 规范“特定于再现操作的附加条目”中的 JS 条目:

包含 JavaScript 脚本的文本字符串或流,应 当动作被触发时执行。

您也可以更改上面的代码来捕获 COSStream 对象; COSStream 是从 COSDictionary 扩展而来的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Apache PDFBox 在 PDF 中查找 javascript 代码 的相关文章

  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • MI设备中即使应用程序被杀死,如何运行后台服务

    您好 我正在使用 alaram 管理器运行后台服务 它工作正常 但对于某些 mi 设备 后台服务无法工作 我使用了服务 但它无法工作 如何在 mi 中运行我的后台服务 MI UI有自己的安全选项 所以你需要的不仅仅是上面提到的粘性服务 你需
  • Java 重写 hashCode() 得到 StackOverflowError

    所以我不太熟悉重写 hashCode 并且我似乎在 hashCode 方法中以某种方式进行了一些无限递归 这是我的场景 我有一个 DuplicateCache 类 它是一个缓存对象 用于检查系统中的重复对象 我有一个静态内部类 Duplic
  • Java:从元素创建 DOM 元素,而不是文档

    如您所知 在 Java 中创建 Dom 元素的正确方法是执行以下操作 import org w3c dom Document import org w3c dom Element Document d Element e e d creat
  • JavaFX - setVisible 隐藏元素但不重新排列相邻节点

    在 JavaFX 中 如果我有一个场景有 2VBox元素和每个VBox有多个Label in it 如果我设置顶部VBox to 无形的 为什么底部VBox 不向上移动顶部的场景VBox was The VBox is 无形的但我希望其他物
  • 为什么 ConcurrentHashMap::putIfAbsent 比 ConcurrentHashMap::computeIfAbsent 更快?

    使用 ConcurrentHashMap 我发现computeIfAbsent 比putIfAbsent 慢两倍 这是简单的测试 import java util ArrayList import java util List import
  • 从 html 页面和 javascript 调用 java webservice

    我正在尝试从 javascript 调用 java 实现的 Web 服务 使用 NetBeans IDE 我读过很多关于 jQuery 和 AJAX 的内容 但我似乎无法掌握它 假设我的 Web 服务 WSDL 位于 http localh
  • jmap - 组织和堆操作会给 jvm 带来开销吗?

    正如标题所述 需要多少开销jmap histo and jmap heap分别带到jvm 如果一个内存敏感的 Java 进程处于OutOfMemory 例如 大约 96 的堆已满 并且无法通过 full gc 清除 其中一项操作是否有可能将
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • 将 RSA 密钥从 BigIntegers 转换为SubjectPublicKeyInfo 形式

    WARNING 最初的问题是关于 PKCS 1 编码密钥 而问题中的实际示例需要SubjectPublicKeyInfo X 509 编码密钥 我目前正致力于在 java 中从头开始实现 RSA 算法 特别是密钥生成方面 现在我的代码可以给
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • struts 教程或示例

    我正在尝试在 Struts 中制作一个登录页面 这个想法是验证用户是否存在等 然后如果有错误 则返回到登录页面 错误显示为红色 典型的登录或任何表单页面验证 我想知道是否有人知道 Struts 中的错误管理教程 我正在专门寻找有关的教程 或
  • Path2D 上的鼠标指针检测

    我构建了一个Path2D http docs oracle com javase 7 docs api java awt geom Path2D html表示由直线组成的未闭合形状 我希望能够检测何时单击鼠标并且鼠标指针靠近路径 在几个像素
  • Java中获取集合的幂集

    的幂集为 1 2 3 is 2 3 2 3 1 2 1 3 1 2 3 1 假设我有一个Set在爪哇中 Set
  • Java中有类似分支/跳转表的东西吗?

    Java有类似分支表或跳转表的东西吗 分支表或跳转表是 根据维基百科 http en wikipedia org wiki Branch table 用于描述使用分支指令表将程序控制 分支 转移到程序的另一部分 或可能已动态加载的不同程序

随机推荐

  • Laravel“Hash::make”替代 url 参数?

    如何在 Laravel 中对 url 参数进行哈希处理 我知道 Hash make 方法 但这是一种密码方法 这些哈希值对 url 不太友好 Laravel 是否有更好的替代方案 这样我就可以对参数进行哈希处理 例如http url key
  • 判断驱动器是分区还是单独的 HDD

    我正在编写自己的文件搜索 为什么是因为我想 可以 不寻找现有的程序 我可以使用 C 获取所有驱动器DriveInfo GetDrives http msdn microsoft com en us library system io dri
  • 如果二进制文件包含字符串类的成员,为什么 C++ 拒绝将结构追加到二进制文件中?

    所以今天我在编程上几乎没有取得任何进展 因为我非常缓慢地意识到 C 是一种类型大小写非常敏感的语言 因为如果结构的成员之一是字符串类类型 我就无法将结构附加到二进制文件 在我发现之前我并不知道情况是这样 我先证明我的观点 此代码将不起作用
  • 成为万事通程序员的好处和优势? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我从事 Web 开发已有 10 年了 主要是 MS 堆栈 但也有一些 LAMP 如今 程序员的选择如此之多 而且就业市场似乎无处不在 在我再次深
  • 从 .xls 文件中读取图像及其位置的参考

    在我的一个项目中 我需要从 xls文件 对于每一行 有一列包含我需要读出的图像 看起来我可以一起读取所有图像 但是我怎样才能获得每个图像的位置 例如列号和行号 以便我可以将这些图像与其他数据关联起来 只要形状是图片 以下都是可能的 impo
  • 从异步 NSURLConnection 更新 NSmenu

    我正在编写一个小系统托盘应用程序 它从 API 获取数据并相应地更新其菜单 但在打开菜单时更新菜单时遇到问题 我什至不知道从哪里开始 所以让我们从头开始吧 我有一个习惯PNLinksLoader其职责是获取数据并解析它的类 void loa
  • 无法将 System.IO.Compression 添加到 SQL Server 中的受信任程序集

    我正在尝试在 NET 4 5 中创建一个 SQLCLR 存储过程来处理 ZIP 文件 明显地System IO Compression不在 SQL Server 的批准列表中 但这是我尝试通过 SQL Server Management S
  • 如何在iPhone SDK中检测PDF文档的方向

    我目前正在使用 CGPDFDocumnentRef 开发一个简单的 PDF 阅读器 当我尝试渲染纵向 PDF 文档时一切都很好 但是当我尝试在横向中渲染一个时 它会显示一个旋转的 PDF 文档 当然 当我在 pdf 阅读器的网络浏览器中查看
  • 如果最后评估的语句是 If 语句,Ruby 中会返回什么

    我的理解是 ruby 返回函数中计算的最后一个语句 如果函数以一个结尾怎么办if评估结果为 false 的语句 def thing input item input hi if item end end puts thing hi clas
  • Spring 5 Reactive - WebExceptionHandler 没有被调用

    我已经尝试了中建议的所有 3 个解决方案处理 spring webflux 中的错误的正确方法是什么 https stackoverflow com questions 43575538 what is the right way to h
  • 为什么python客户端收不到SSE事件?

    我有一个 python 客户端 使用 node js API 从服务器监听 SSE 事件 流程是我通过以下方式向 node js API 发送了一个事件call notification py并运行seevents py在循环中使用run
  • Numpy 矩阵乘法广播

    我有一个由 N 个 3x3 数组 矩阵的集合 尽管数据类型为 np ndarray 组成的数组 还有一个由 N 个 3x1 数组 向量的集合 组成的数组 我想要做的是将每个矩阵乘以每个向量 所以我期望得到 N 个 3x1 数组 简单的例子
  • 在我的案例中,如何将一种布局嵌入另一种布局?

    如果我有一个名为底部 xml 底部 xml 请参阅此文档重用布局 http android developers blogspot com 2009 02 android layout tricks 2 reusing layouts ht
  • MVC 4 razor 数据注释只读

    ReadOnly 属性似乎不在 MVC 4 中 Editable false 属性不能按我希望的方式工作 有类似的东西有效吗 如果不是 那么我如何制作自己的 ReadOnly 属性 其工作方式如下 public class aModel R
  • 当前位置更改时 MKRoute 更新 MKPolyline Overlay

    我用谷歌搜索了很多 但无法让它发挥作用 在我的 MKMapView 中 我有一个自定义 MKAnnotationView 我可以将其放置在任何地方 还有代表我当前位置的点 我可以 显示方向 计算自定义注释和当前位置之间的 MKDirecti
  • 将 unique_ptr 与 gsl_vector 结合使用

    我最喜欢的方面之一unique ptr是它提供的自动内存管理 我想用unique ptr与 GSL 向量之类的东西 然而 gsl vector有自己的释放内存的机制 gsl vector free 有没有办法强制唯一指针使用GSL的向量释放
  • 为什么 iostream 在 MCU 上占用如此多的闪存空间?

    我使用 GCC 5 2 0 编译 EFM32 MCU 基于 Cortex M 内核 的代码 当我想要时 我注意到代码大小急剧增加 include
  • iOS UrlSession.shared.dataTask 删除 utf-8“+”字符并替换为“”

    我正在使用 x www form endoded 数据创建对 API 的登录调用 我在 Postman 中创建了一个 POST 并收到了 200 回复 我使用Postman的导出功能生成Android的OKHTTP代码和iOS的NSURL代
  • 如何找到堆栈深度?

    我想用单元格替换以下函数调用 参考 从 C 中的任何线程获取调用堆栈 https stackoverflow com questions 1310669 get call stack from any thread within c int
  • 使用 Apache PDFBox 在 PDF 中查找 javascript 代码

    我的目标是提取和处理 PDF 文档可能包含的任何 JavasCript 代码 通过在编辑器中打开 PDF 我可以看到如下对象 402 0 obj lt JavaScript JS n r n Set day 25 r n FormRoute