MCPcopy Create free account
hub / github.com/dwgx/WindsurfAPI / extractPdfText

Function extractPdfText

src/pdf.js:22–76  ·  view source on GitHub ↗
(buf)

Source from the content-addressed store, hash-verified

20 * @returns {string} Extracted text, or empty string if no text layer
21 */
22export function extractPdfText(buf) {
23 const pages = [];
24 let streamCount = 0;
25 let totalDecoded = 0;
26
27 // Find all stream...endstream blocks
28 let pos = 0;
29 while (pos < buf.length) {
30 const streamStart = buf.indexOf('stream\n', pos);
31 if (streamStart === -1) break;
32
33 const dataStart = streamStart + 7; // skip "stream\n"
34 // Handle \r\n after "stream"
35 const actualStart = buf[streamStart + 6] === 0x0d ? dataStart + 1 : dataStart;
36
37 const endStream = buf.indexOf('\nendstream', actualStart);
38 if (endStream === -1) break;
39
40 const streamData = buf.subarray(actualStart, endStream);
41 streamCount++;
42 if (streamCount > MAX_STREAMS) throw new Error('PDF stream count exceeds safety limit');
43
44 // Check if this stream has FlateDecode by looking back at the dictionary
45 const dictStart = Math.max(0, streamStart - 500);
46 const dictText = buf.subarray(dictStart, streamStart).toString('latin1');
47 const isFlate = dictText.includes('FlateDecode');
48
49 let decoded;
50 try {
51 if (isFlate) {
52 const inflated = inflateSync(streamData, { maxOutputLength: MAX_STREAM_DECODED });
53 if (inflated.length > MAX_STREAM_DECODED) throw new Error('PDF decoded content exceeds safety limit');
54 totalDecoded += inflated.length;
55 if (totalDecoded > MAX_TOTAL_DECODED) throw new Error('PDF decoded content exceeds safety limit');
56 decoded = inflated.toString('latin1');
57 } else {
58 totalDecoded += streamData.length;
59 if (streamData.length > MAX_STREAM_DECODED || totalDecoded > MAX_TOTAL_DECODED) throw new Error('PDF decoded content exceeds safety limit');
60 decoded = streamData.toString('latin1');
61 }
62 } catch (e) {
63 if (/limit|exceed|maxOutputLength|Buffer larger/i.test(e.message) || e.code === 'ERR_BUFFER_TOO_LARGE') throw e;
64 pos = endStream + 10;
65 continue;
66 }
67
68 // Extract text from PDF operators
69 const text = extractTextOps(decoded);
70 if (text.trim()) pages.push(text.trim());
71
72 pos = endStream + 10;
73 }
74
75 return pages.join('\n\n');
76}
77
78/**
79 * Extract text from PDF content stream operators.

Callers 1

tryExtractPdfFunction · 0.85

Calls 2

extractTextOpsFunction · 0.85
pushMethod · 0.80

Tested by

no test coverage detected