第二阶段代码
This commit is contained in:
243
apps/web-ele/src/views/database/info/components/pdf.ts
Normal file
243
apps/web-ele/src/views/database/info/components/pdf.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
let PDFLib: any = null
|
||||
|
||||
interface PDFLibModule {
|
||||
PDFDocument: {
|
||||
load(bytes: ArrayBuffer, options?: { ignoreEncryption?: boolean }): Promise<any>
|
||||
}
|
||||
PDFName: {
|
||||
of(name: string): any
|
||||
}
|
||||
PDFDict: any
|
||||
PDFArray: any
|
||||
}
|
||||
|
||||
const loadPdfLib = (): Promise<PDFLibModule> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (PDFLib) {
|
||||
resolve(PDFLib)
|
||||
return
|
||||
}
|
||||
|
||||
const script = document.createElement('script')
|
||||
script.src = '/static/js/pdf-lib.min.js'
|
||||
script.onload = () => {
|
||||
PDFLib = (window as any).PDFLib
|
||||
resolve(PDFLib)
|
||||
}
|
||||
script.onerror = reject
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
const checkActionForJavaScript = (
|
||||
action: any,
|
||||
PDFDict: any,
|
||||
PDFName: any,
|
||||
PDFArray: any,
|
||||
): boolean => {
|
||||
if (!(action instanceof PDFDict)) return false
|
||||
|
||||
const subtype = action.lookup(PDFName.of('S'))
|
||||
if (subtype?.toString() === '/JavaScript') {
|
||||
return true
|
||||
}
|
||||
|
||||
const js = action.lookup(PDFName.of('JS'))
|
||||
if (js) {
|
||||
return true
|
||||
}
|
||||
|
||||
const next = action.lookup(PDFName.of('Next'))
|
||||
if (next instanceof PDFArray) {
|
||||
for (let i = 0; i < next.size(); i++) {
|
||||
if (checkActionForJavaScript(next.lookup(i), PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if (next instanceof PDFDict) {
|
||||
if (checkActionForJavaScript(next, PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const checkFieldForJavaScript = (
|
||||
field: any,
|
||||
PDFDict: any,
|
||||
PDFName: any,
|
||||
PDFArray: any,
|
||||
): boolean => {
|
||||
if (!(field instanceof PDFDict)) return false
|
||||
|
||||
const aa = field.lookup(PDFName.of('AA'))
|
||||
if (aa instanceof PDFDict) {
|
||||
const actionKeys = ['K', 'F', 'V', 'C', 'E', 'X', 'D', 'U', 'Fo', 'PO', 'PC', 'PV', 'PI']
|
||||
|
||||
for (const key of actionKeys) {
|
||||
const action = aa.lookup(PDFName.of(key))
|
||||
if (action && checkActionForJavaScript(action, PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const kids = field.lookup(PDFName.of('Kids'))
|
||||
if (kids instanceof PDFArray) {
|
||||
for (let i = 0; i < kids.size(); i++) {
|
||||
if (checkFieldForJavaScript(kids.lookup(i), PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const checkAcroFormForJavaScript = (
|
||||
acroForm: any,
|
||||
PDFDict: any,
|
||||
PDFName: any,
|
||||
PDFArray: any,
|
||||
): boolean => {
|
||||
if (!(acroForm instanceof PDFDict)) return false
|
||||
|
||||
const co = acroForm.lookup(PDFName.of('CO'))
|
||||
if (co instanceof PDFArray) {
|
||||
for (let i = 0; i < co.size(); i++) {
|
||||
if (checkFieldForJavaScript(co.lookup(i), PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fields = acroForm.lookup(PDFName.of('Fields'))
|
||||
if (fields instanceof PDFArray) {
|
||||
for (let i = 0; i < fields.size(); i++) {
|
||||
if (checkFieldForJavaScript(fields.lookup(i), PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const checkAnnotationForJavaScript = (
|
||||
annot: any,
|
||||
PDFDict: any,
|
||||
PDFName: any,
|
||||
PDFArray: any,
|
||||
): boolean => {
|
||||
if (!(annot instanceof PDFDict)) return false
|
||||
|
||||
const aa = annot.lookup(PDFName.of('AA'))
|
||||
if (aa instanceof PDFDict) {
|
||||
const actionKeys = ['E', 'X', 'D', 'U', 'Fo', 'Bl', 'PO', 'PC', 'PV', 'PI']
|
||||
|
||||
for (const key of actionKeys) {
|
||||
const action = aa.lookup(PDFName.of(key))
|
||||
if (action && checkActionForJavaScript(action, PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const action = annot.lookup(PDFName.of('A'))
|
||||
if (action && checkActionForJavaScript(action, PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const checkPageForJavaScript = (
|
||||
page: any,
|
||||
PDFDict: any,
|
||||
PDFName: any,
|
||||
PDFArray: any,
|
||||
): boolean => {
|
||||
if (!(page instanceof PDFDict)) return false
|
||||
|
||||
const aa = page.lookup(PDFName.of('AA'))
|
||||
if (aa instanceof PDFDict) {
|
||||
const actionKeys = ['O', 'C']
|
||||
|
||||
for (const key of actionKeys) {
|
||||
const action = aa.lookup(PDFName.of(key))
|
||||
if (action && checkActionForJavaScript(action, PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const annots = page.lookup(PDFName.of('Annots'))
|
||||
if (annots instanceof PDFArray) {
|
||||
for (let i = 0; i < annots.size(); i++) {
|
||||
if (checkAnnotationForJavaScript(annots.lookup(i), PDFDict, PDFName, PDFArray)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const checkPdfJavaScript = async (bytes: ArrayBuffer): Promise<boolean> => {
|
||||
if (!PDFLib) {
|
||||
console.error('PDFLib not loaded')
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
const { PDFDocument, PDFName, PDFDict, PDFArray } = PDFLib
|
||||
const pdfDoc = await PDFDocument.load(bytes, { ignoreEncryption: true })
|
||||
const catalog = pdfDoc.catalog
|
||||
|
||||
const names = catalog.lookup(PDFName.of('Names'))
|
||||
if (names instanceof PDFDict) {
|
||||
const javaScriptDict = names.lookup(PDFName.of('JavaScript'))
|
||||
if (javaScriptDict instanceof PDFDict) {
|
||||
console.log('检测到文档级 JavaScript')
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const openAction = catalog.lookup(PDFName.of('OpenAction'))
|
||||
if (openAction && checkActionForJavaScript(openAction, PDFDict, PDFName, PDFArray)) {
|
||||
console.log('检测到 OpenAction 中的 JavaScript')
|
||||
return true
|
||||
}
|
||||
|
||||
const acroForm = catalog.lookup(PDFName.of('AcroForm'))
|
||||
if (acroForm && checkAcroFormForJavaScript(acroForm, PDFDict, PDFName, PDFArray)) {
|
||||
console.log('检测到表单中的 JavaScript')
|
||||
return true
|
||||
}
|
||||
|
||||
const pages = catalog.lookup(PDFName.of('Pages'))
|
||||
if (pages instanceof PDFDict) {
|
||||
const kids = pages.lookup(PDFName.of('Kids'))
|
||||
if (kids instanceof PDFArray) {
|
||||
for (let i = 0; i < kids.size(); i++) {
|
||||
const page = kids.lookup(i)
|
||||
if (page instanceof PDFDict && checkPageForJavaScript(page, PDFDict, PDFName, PDFArray)) {
|
||||
console.log('检测到页面中的 JavaScript')
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
} catch (error) {
|
||||
console.error('Error checking JavaScript:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
loadPdfLib,
|
||||
checkPdfJavaScript,
|
||||
}
|
||||
Reference in New Issue
Block a user