用于验证PDF和Excel文件类型的模式

时间:2014-06-03 18:32:15

标签: java excel pdf pattern-matching bytearray

我有一个允许用户上传附件的网络应用;但是,我想将用户限制为仅限某些文件类型 - Adob​​e PDF和MS Excel。 原因是在用户提交文档进行处理和工作流程之前,我将汇总一些附件并创建一个PDF报告。

我做了一些研究并转换DOC(X),RTF等......会很头疼。 而且每个人都会在理论上和#34;如果附件都是PDF格式,则可以获得更好的查看可移植性。

目前我正在检查mime类型 -

PDF - "application/pdf"

XLS(X) -

  • "application/vnd.ms-excel"
  • "application/msexcel"
  • "application/x-msexcel"
  • "application/x-ms-excel"
  • "application/x-excel"
  • "application/x-dos_ms_excel"
  • "application/xls"
  • "application/x-xls"

这很有效,但我注意到我可以采用.docx文件并将其更改为.pdf并成功绕过此检查。< / p>

为了解决这个问题,我计划进一步检查实际文件的标题。

根据文件签名的this library

PDF将包含以下标题 -

25 50 44 46

它将有以下预告片之一 -

  • 0A 25 25 45 4F 46 (.%%EOF)
  • 0A 25 25 45 4F 46 0A (.%%EOF.)
  • 0D 0A 25 25 45 4F 46 0D 0A (..%%EOF..)
  • 0D 25 25 45 4F 46 0D (.%%EOF.)

到目前为止,我已经有了执行此检查的框架代码 -

**编辑反映回答**

public boolean confirmAttachmentAuthenticity(ProposalDevelopmentForm form, String mimeType) {
    boolean authentic = true;
    // Case:  User is attempting to upload a "PDF" document
    if (mimeType.equals(ADOBE_PDF_CONTENT_TYPE)) {
        try {
            InputStream inputStream = form.getNewNarrative().getNarrativeFile().getInputStream();
            PdfReader pdfReader = new PdfReader(inputStream);
            int numberOfPages = pdfReader.getNumberOfPages();
            if (numberOfPages > 0) {
                // Success - valid PDF
                info(form.getNewNarrative().getNarrativeFile().getFileName() + " validated authentic Adobe PDF file");
            }
        }
        catch(IOException ioe) {
            // Failure - masquerading PDF
            authentic = false;
            info(form.getNewNarrative().getNarrativeFile().getFileName() + " is not an authentic Adobe PDF file.");
            reportError("newNarrative.narrativeFile",
                KeyConstants.ERROR_ATTACHMENT_PDF_NOT_AUTHENTIC,
                form.getNewNarrative().getNarrativeFile().getFileName());
        }
        catch (Exception e) {
            // Failure - other causes
            authentic = false;
            info(form.getNewNarrative().getNarrativeFile().getFileName() + " could not be authenticated at this time.");
            e.printStackTrace();
            reportError("newNarrative.narrativeFile",
                KeyConstants.ERROR_ATTACHMENT_TYPE_CORRUPTED,
                form.getNewNarrative().getNarrativeFile().getFileName());
        }
    }
    // Case: User is attempting to upload an "EXCEL" spreadsheet
    else {
        try {
            InputStream inputStream = form.getNewNarrative().getNarrativeFile().getInputStream();
            POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);
            HSSFWorkbook workBook = new HSSFWorkbook(fileSystem);
            int numberOfSheets = workBook.getNumberOfSheets();
            if (numberOfSheets > 0) {
                // Success - valid Excel Spreadsheet
                info(form.getNewNarrative().getNarrativeFile().getFileName() + " validated authentic MS Excel file");
            }
        }
        catch(IOException ioe) {
            // Failure - masquerading XLS(X)
            authentic = false;
            info(form.getNewNarrative().getNarrativeFile().getFileName() + " is not an authentic MS Excel file.");
            reportError("newNarrative.narrativeFile",
                KeyConstants.ERROR_ATTACHMENT_XLS_NOT_AUTHENTIC,
                form.getNewNarrative().getNarrativeFile().getFileName());
        }
        catch (Exception e) {
            // Failure - other causes
            authentic = false;
            info(form.getNewNarrative().getNarrativeFile().getFileName() + " could not be authenticated at this time.");
            e.printStackTrace();
            reportError("newNarrative.narrativeFile",
                    KeyConstants.ERROR_ATTACHMENT_TYPE_CORRUPTED,
                    form.getNewNarrative().getNarrativeFile().getFileName());
        }
    }
    return authentic;
}

我认为最好的方法是使用BinarySearch方法来执行此操作。 但是,我还阅读了一些人们建议将fileData转换为字符串然后使用正则表达式的帖子。

任何想法都会受到赞赏。

如果你可以帮助我开始填写我的骨架代码中的任何一个案例,那么奖励积分。 我的逐位逻辑知识生疏了。这是我过去一年编写的高级客户端代码所能得到的。

1 个答案:

答案 0 :(得分:1)

永远不会信任来自客户端的传入请求,标头值可以更改,并且它不会反映请求正文中的内容。

使用第三方库来检查文件是PDF还是Excel或其他内容。

检查文档是否为PDF,例如尝试使用iText打开文档,Excel尝试使用Apache POI打开文档。