@@ -208,4 +208,199 @@ public function testGetDecodedStreamThrowsWhenFilterErrorsAreNotIgnored(): void
208208 $ this ->expectException (PPException::class);
209209 $ parser ->getDecodedStreamPublic (['UnknownFilter ' ], 'sample-data ' );
210210 }
211+
212+ /**
213+ * @throws \Com\Tecnick\Pdf\Parser\Exception
214+ */
215+ public function testParentIndirectObjectFindsObjectAfterOffsetShift (): void
216+ {
217+ $ parser = new ParserHarness ();
218+ $ parser ->setPdfDataPublic ("%PDF-1.7 \nX1 0 obj \nendobj \n" );
219+ $ parser ->setRawObjectQueue ([
220+ ['numeric ' , '7 ' , 16 ],
221+ ['endobj ' , 'endobj ' , 22 ],
222+ ]);
223+
224+ $ obj = $ parser ->callParentGetIndirectObject ('1_0 ' , 9 , true );
225+
226+ $ this ->assertSame ([['numeric ' , '7 ' , 16 ]], $ obj );
227+ }
228+
229+ /**
230+ * @throws \Com\Tecnick\Pdf\Parser\Exception
231+ */
232+ public function testGetFiltersHandlesMissingAndInvalidArrayPayload (): void
233+ {
234+ $ parser = new ParserHarness ();
235+
236+ $ filters = ['FlateDecode ' ];
237+ $ this ->assertSame ($ filters , $ parser ->getFiltersPublic ($ filters , [['/ ' , 'Filter ' , 0 ]], 0 ));
238+
239+ $ invalid = [
240+ ['/ ' , 'Filter ' , 0 ],
241+ ['[ ' , 'invalid ' , 0 ],
242+ ];
243+ $ this ->assertSame ([], $ parser ->getFiltersPublic ([], $ invalid , 0 ));
244+ }
245+
246+ /**
247+ * @throws \Com\Tecnick\Pdf\Parser\Exception
248+ */
249+ public function testGetDecodeParmsHandlesDictionaryArrayAndMissingValues (): void
250+ {
251+ $ parser = new ParserHarness ();
252+
253+ $ this ->assertSame ([], $ parser ->getDecodeParmsPublic ([['/ ' , 'DecodeParms ' , 0 ]], 0 ));
254+
255+ $ dict = [
256+ ['/ ' , 'DecodeParms ' , 0 ],
257+ [
258+ '<< ' ,
259+ [
260+ ['/ ' , 'Columns ' , 0 ],
261+ ['numeric ' , '5 ' , 0 ],
262+ ['/ ' , 'EarlyChange ' , 0 ],
263+ ['true ' , 'true ' , 0 ],
264+ ['/ ' , 'FilterName ' , 0 ],
265+ ['/ ' , 'FlateDecode ' , 0 ],
266+ ['/ ' , 'Text ' , 0 ],
267+ ['string ' , 'abc ' , 0 ],
268+ ['/ ' , 'Ignored ' , 0 ],
269+ ['[ ' , [], 0 ],
270+ ],
271+ 0 ,
272+ ],
273+ ];
274+
275+ $ this ->assertSame (
276+ [
277+ 'Columns ' => 5 ,
278+ 'EarlyChange ' => true ,
279+ 'FilterName ' => 'FlateDecode ' ,
280+ 'Text ' => 'abc ' ,
281+ ],
282+ $ parser ->getDecodeParmsPublic ($ dict , 0 ),
283+ );
284+
285+ $ array = [
286+ ['/ ' , 'DecodeParms ' , 0 ],
287+ [
288+ '[ ' ,
289+ [
290+ ['null ' , 'null ' , 0 ],
291+ [
292+ '<< ' ,
293+ [
294+ ['/ ' , 'Rows ' , 0 ],
295+ ['numeric ' , '2 ' , 0 ],
296+ ['/ ' , 'Enabled ' , 0 ],
297+ ['false ' , 'false ' , 0 ],
298+ ],
299+ 0 ,
300+ ],
301+ ],
302+ 0 ,
303+ ],
304+ ];
305+
306+ $ this ->assertSame (
307+ [
308+ 'Rows ' => 2 ,
309+ 'Enabled ' => false ,
310+ ],
311+ $ parser ->getDecodeParmsPublic ($ array , 0 ),
312+ );
313+ }
314+
315+ /**
316+ * @throws \Com\Tecnick\Pdf\Parser\Exception
317+ */
318+ public function testDecodeStreamHandlesEmptyStreamAndDecodeParmsExtraction (): void
319+ {
320+ $ parser = new ParserHarness (['ignore_filter_errors ' => true ]);
321+
322+ $ this ->assertSame (['' , []], $ parser ->decodeStreamPublic ([], '' ));
323+
324+ $ sdic = [
325+ ['/ ' , 'Filter ' , 0 ],
326+ ['/ ' , 'UnknownFilter ' , 0 ],
327+ ['/ ' , 'DecodeParms ' , 0 ],
328+ [
329+ '<< ' ,
330+ [
331+ ['/ ' , 'Columns ' , 0 ],
332+ ['numeric ' , '3 ' , 0 ],
333+ ['/ ' , 'Predictor ' , 0 ],
334+ ['numeric ' , '12 ' , 0 ],
335+ ],
336+ 0 ,
337+ ],
338+ ];
339+
340+ $ result = $ parser ->decodeStreamPublic ($ sdic , 'abc ' );
341+ $ this ->assertSame ('abc ' , $ result [0 ]);
342+ $ this ->assertSame (['UnknownFilter ' ], $ result [1 ]);
343+ }
344+
345+ /**
346+ * @throws \Com\Tecnick\Pdf\Parser\Exception
347+ */
348+ public function testParentIndirectObjectReturnsNullObjectWhenSearchMissesTwice (): void
349+ {
350+ $ parser = new ParserHarness ();
351+ $ parser ->setPdfDataPublic ("%PDF-1.7 \nno objects \n" );
352+
353+ $ obj = $ parser ->callParentGetIndirectObject ('1_0 ' , 2 , true );
354+
355+ $ this ->assertSame ([['null ' , 'null ' , 3 ]], $ obj );
356+ }
357+
358+ /**
359+ * @throws \Com\Tecnick\Pdf\Parser\Exception
360+ */
361+ public function testGetFiltersSkipsSlashEntriesWithNonStringNames (): void
362+ {
363+ $ parser = new ParserHarness ();
364+ $ sdic = [
365+ ['/ ' , 'Filter ' , 0 ],
366+ [
367+ '[ ' ,
368+ [
369+ ['/ ' , [['numeric ' , '1 ' , 0 ]], 0 ],
370+ ['/ ' , 'FlateDecode ' , 0 ],
371+ ],
372+ 0 ,
373+ ],
374+ ];
375+
376+ $ filters = $ parser ->getFiltersPublic ([], $ sdic , 0 );
377+ $ this ->assertSame (['FlateDecode ' ], $ filters );
378+ }
379+
380+ /**
381+ * @throws \Com\Tecnick\Pdf\Parser\Exception
382+ */
383+ public function testGetDecodeParmsSkipsInvalidPairsAcrossLoopChecks (): void
384+ {
385+ $ parser = new ParserHarness ();
386+ $ sdic = [
387+ ['/ ' , 'DecodeParms ' , 0 ],
388+ [
389+ '<< ' ,
390+ [
391+ ['numeric ' , '0 ' , 0 ],
392+ ['numeric ' , '1 ' , 0 ],
393+ ['/ ' , 'MissingValue ' , 0 ],
394+ ['null ' , 'null ' , 0 ],
395+ ['/ ' , 'Valid ' , 0 ],
396+ ['numeric ' , '7 ' , 0 ],
397+ ['/ ' , 'DanglingKey ' , 0 ],
398+ ],
399+ 0 ,
400+ ],
401+ ];
402+
403+ $ params = $ parser ->getDecodeParmsPublic ($ sdic , 0 );
404+ $ this ->assertSame (['Valid ' => 7 ], $ params );
405+ }
211406}
0 commit comments