0

I'm triying to put a text into some pdfs with TCPDI.

It works fine in most pdfs, but in some pdf the code get stuck when it reachs the useTemplate() function, and got 500 error (Maximum time exceded).

They are not long pdf (1,2,3 pages max), and anothers pdfs with more pages works fine. Here is my code:

$pdf = new TCPDI();

$pageCount = $pdf->setSourceFile($path);

for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {

    $templateId = $pdf->importPage($pageNo);

    $size = $pdf->getTemplateSize($templateId);

    if ($size['w'] > $size['h']) {
        $pdf->AddPage('L', array($size['w'], $size['h']));
    } else {
        $pdf->AddPage('P', array($size['w'], $size['h']));
    }

    $pdf->useTemplate($templateId); //Here is where it takes so long that it exceeds time

$pdf->SetFont('Helvetica');
$pdf->SetFontSize(10);
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(2, 0);
$pdf->Write(0, 'Code nº 4');

}

$pdf->Output($file,'D'); 

Is there any prop of the pdf that can make it stay locked? There are alterntives?

I have a code that process several pdf with this code in a loop an put they into a zip, and when in the chain is one pdf that jam the code the zip obviously dind't process, so if there are a way to detect what pdf are goingo to give me problem, I cant jump over there and generate the zip with the goods one.

I have not control over the pdfs, their are upload by a lot of clients

EDIT: In log there are more than a million of lines similar to PHP Warning: Illegal string offset 'DAmip' in ...\TCPDF\tcpdi_parser.php on line 712 before Maximum execution Time Fatal Error

  • Did you checked your PHP error logs for details about the error? You cannot use this code in a loop because it sends the resulting PDF to the client and this can only happen for a single file. – Jan Slabon Feb 12 '20 at 09:05
  • Hi, when I use this code in a loop I'm not sending the result to the client, I'm storing the result into a server temporal folder to make a zip later when all pds are proccessed. Anytime the problem is the same if I use this code to edit only one pdf. (as I said it happend with some pdf exclusively, most of they works fine.) Error log is huge with this last lines(more than millions lines): PHP Warning: Illegal string offset 'DAmip' in ...\TCPDF\tcpdi_parser.php on line 712 And finally: PHP Fatal error: Maximum execution time of 300 seconds exceeded in ...TCPDF\tcpdi_parser.php on line 712 – Ivan Ortiz Feb 13 '20 at 10:24
  • Looks like a bug in the used parser. You should think about switching to a more reliable solution such as the official [FPDI](https://setasing.com/fpdi) + the [FPDI PDF-Parser](https://setasign.com/fpdi-pdf-parser) (both created by us - the later one is not free but adds support for reading PDFs with compressed cross-reference streams and object streams). Generally you should also know that [you cannot edit a PDF with FPDI](https://www.setasign.com/support/faq/fpdi/can-i-edit-a-pdf-document-with-fpdi/#question-82). – Jan Slabon Feb 13 '20 at 16:32

2 Answers2

1

Same problem for me.

I 'solved' the situation adding the line set_time_limit(10); before the line

while (strspn($data{$offset}, "\x00\x09\x0a\x0c\x0d\x20") == 1) {

I know it's not the right solution but, at least, doesn't block your program

ezio4df
  • 3,541
  • 6
  • 16
  • 31
  • Sorry but it's a very bad solution. The problem is still here and PHP Error log file will always be flowed by thousand lines. I spend a day to find a solution (see my answer). – Jerry Dec 11 '22 at 17:33
0

I suggest you to read my comment on GitHub : https://github.com/pauln/tcpdi_parser/pull/23

The function getDictValue() of tcpdi_parser.pdf is incompatible with some PDF files.

All is explained in my response dated of this day.

Suggested modification :

private function getDictValue($offset, &$data) {
    $objval = array();

    // Extract dict from data
    $i = 1;
    $dict = "";
    $offset+= 2;
    $is_bracket = false;
    do {
        if ($data[$offset] == "[") {
            $is_bracket = true;
            $dict.= $data[$offset];
        } else if ($data[$offset] == "]") {
            $is_bracket = false;
            $dict.= $data[$offset];
        } else if (!$is_bracket && ($data[$offset] == "<") && ($data[$offset + 1] == "<")) {
            $i++;
            $dict.= "<<";
            $offset++;
        } else if (!$is_bracket && ($data[$offset] == ">") && ($data[$offset + 1] == ">")) {
            $i--;
            $dict.= ">>";
            $offset++;
        } else {
            $dict.= $data[$offset];
        }
        $offset++;
    } while ($i > 0);
    
    // Now that we have just the dict, parse it.
    $dictoffset = 0;
    do {
        // Get dict element.
        file_put_contents("debug_tcpdi.txt", "getRawObject($dictoffset, data) depuis getDictValue()" . "\r\n", FILE_APPEND);
        list($key, $eloffset) = $this->getRawObject($dictoffset, $dict);
        if ($key[0] == '>>') {
            break;
        }
        file_put_contents("debug_tcpdi.txt", "getRawObject($eloffset, data) depuis getDictValue()" . "\r\n", FILE_APPEND);
        list($element, $dictoffset) = $this->getRawObject($eloffset, $dict);
        $objval['/'.$key[1]] = $element;
        unset($key);
        unset($element);
    } while (true);

    return array($objval, $offset);
}
Jerry
  • 1,141
  • 1
  • 13
  • 18