From 3a7ed278e58c41523967e2fc81aa139668da8f77 Mon Sep 17 00:00:00 2001 From: Eduard Wisch Date: Thu, 9 Apr 2026 15:50:36 +0200 Subject: [PATCH] Ajax-Endpoints: Fatal-Handler + Output-Buffer, mysoc defensiv [deploy] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ajax/_inc.php: ob_start() + register_shutdown_function fangen PHP Notices und Fatals auf, geben strukturiertes JSON zurück (vorher Server-Fehler 'kein JSON' weil PHP-Warning mitten im Body stand). - generate_pdf.php/preview_pdf.php: mysoc, logo-Pfad defensiv geprüft. --- ajax/_inc.php | 25 +++++++++++++++++++++++++ ajax/generate_pdf.php | 9 +++++++-- ajax/preview_pdf.php | 9 +++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/ajax/_inc.php b/ajax/_inc.php index e33601f..fa2453e 100644 --- a/ajax/_inc.php +++ b/ajax/_inc.php @@ -20,8 +20,13 @@ require_once __DIR__.'/../lib/bericht.lib.php'; header('Content-Type: application/json; charset=utf-8'); +// Output-Buffer: jeder PHP-Notice/Warning landet sonst mitten im JSON +// und macht es auf dem Client unparsebar ("Server-Fehler (kein JSON)"). +if (!ob_get_level()) ob_start(); + function bericht_ajax_fail($msg, $code = 400) { + while (ob_get_level()) ob_end_clean(); http_response_code($code); echo json_encode(array('success' => false, 'error' => $msg)); exit; @@ -29,10 +34,30 @@ function bericht_ajax_fail($msg, $code = 400) function bericht_ajax_ok($data = array()) { + // Verworfenen Output aus ob_start() wegwerfen, nur unser JSON rausschicken + while (ob_get_level() > 1) ob_end_clean(); + $trash = ob_get_clean(); + if ($trash && getenv('BERICHT_DEBUG')) error_log('[bericht-ajax] verworfener Output: '.substr($trash, 0, 500)); echo json_encode(array_merge(array('success' => true), $data)); exit; } +// Fatal-Handler: wenn etwas im PDF-Pfad explodiert, trotzdem JSON zurückgeben +register_shutdown_function(function () { + $err = error_get_last(); + if ($err && in_array($err['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR), true)) { + while (ob_get_level()) ob_end_clean(); + if (!headers_sent()) { + header('Content-Type: application/json; charset=utf-8'); + http_response_code(500); + } + echo json_encode(array( + 'success' => false, + 'error' => 'PHP Fatal: '.$err['message'].' @ '.basename($err['file']).':'.$err['line'], + )); + } +}); + // Token-Check if (!isset($_REQUEST['token']) || $_REQUEST['token'] !== newToken() && $_REQUEST['token'] !== $_SESSION['token']) { // Dolibarr-Standard erlaubt aktuellen Token; einfache Prüfung: diff --git a/ajax/generate_pdf.php b/ajax/generate_pdf.php index 57093ce..9824983 100644 --- a/ajax/generate_pdf.php +++ b/ajax/generate_pdf.php @@ -52,8 +52,13 @@ if ($fpdi_loaded && class_exists('BerichtPdfFpdi')) { $pdf->SetCreator('Dolibarr Bericht-Modul'); $pdf->SetAuthor($user->getFullName($langs)); $pdf->SetTitle($bericht->titel ?: $bericht->ref); -$logo_path = !empty($mysoc->logo) ? $conf->mycompany->dir_output.'/logos/'.$mysoc->logo : ''; -$pdf->berichtInit($bericht->titel ?: $bericht->ref, $mysoc->name ?? '', $logo_path); +global $mysoc; +$logo_path = ''; +if (!empty($mysoc->logo) && isset($conf->mycompany->dir_output)) { + $logo_path = $conf->mycompany->dir_output.'/logos/'.$mysoc->logo; + if (!file_exists($logo_path)) $logo_path = ''; +} +$pdf->berichtInit($bericht->titel ?: $bericht->ref, (isset($mysoc) && !empty($mysoc->name)) ? $mysoc->name : '', $logo_path); $pdf->SetMargins(10, 30, 10); $pdf->SetAutoPageBreak(true, 16); $pdf->setPrintHeader(true); diff --git a/ajax/preview_pdf.php b/ajax/preview_pdf.php index 2e1ace6..1c319f1 100644 --- a/ajax/preview_pdf.php +++ b/ajax/preview_pdf.php @@ -62,8 +62,13 @@ if ($fpdi_loaded && class_exists('BerichtPdfFpdi')) { $pdf->SetCreator('Dolibarr Bericht-Modul (Vorschau)'); $pdf->SetAuthor($user->getFullName($langs)); $pdf->SetTitle(($bericht->titel ?: $bericht->ref).' [Vorschau]'); -$logo_path = !empty($mysoc->logo) ? $conf->mycompany->dir_output.'/logos/'.$mysoc->logo : ''; -$pdf->berichtInit($bericht->titel ?: $bericht->ref, $mysoc->name ?? '', $logo_path); +global $mysoc; +$logo_path = ''; +if (!empty($mysoc->logo) && isset($conf->mycompany->dir_output)) { + $logo_path = $conf->mycompany->dir_output.'/logos/'.$mysoc->logo; + if (!file_exists($logo_path)) $logo_path = ''; +} +$pdf->berichtInit($bericht->titel ?: $bericht->ref, (isset($mysoc) && !empty($mysoc->name)) ? $mysoc->name : '', $logo_path); $pdf->SetMargins(10, 30, 10); $pdf->SetAutoPageBreak(true, 16); $pdf->setPrintHeader(true);