diff --git a/generated/8.6/functionsList.php b/generated/8.6/functionsList.php index 2177267c..03ac5199 100644 --- a/generated/8.6/functionsList.php +++ b/generated/8.6/functionsList.php @@ -644,6 +644,7 @@ 'parse_url', 'passthru', 'pclose', + 'pcntl_exec', 'pcntl_getcpuaffinity', 'pcntl_getpriority', 'pcntl_setcpuaffinity', @@ -654,9 +655,11 @@ 'pcntl_sigprocmask', 'pcntl_sigtimedwait', 'pcntl_sigwaitinfo', + 'pcntl_unshare', 'pfsockopen', 'pg_cancel_query', 'pg_change_password', + 'pg_close_stmt', 'pg_connect', 'pg_connection_reset', 'pg_convert', @@ -976,12 +979,14 @@ 'ssh2_exec', 'ssh2_forward_accept', 'ssh2_forward_listen', + 'ssh2_keepalive_send', 'ssh2_publickey_add', 'ssh2_publickey_init', 'ssh2_publickey_remove', 'ssh2_scp_recv', 'ssh2_scp_send', 'ssh2_send_eof', + 'ssh2_send_signal', 'ssh2_sftp', 'ssh2_sftp_chmod', 'ssh2_sftp_lstat', diff --git a/generated/8.6/pcntl.php b/generated/8.6/pcntl.php index 6a1268f7..3c25d175 100644 --- a/generated/8.6/pcntl.php +++ b/generated/8.6/pcntl.php @@ -4,6 +4,23 @@ use Safe\Exceptions\PcntlException; +/** + * @param string $path + * @param array $args + * @param array $env_vars + * @throws PcntlException + * + */ +function pcntl_exec(string $path, array $args = [], array $env_vars = []): void +{ + error_clear_last(); + $safeResult = \pcntl_exec($path, $args, $env_vars); + if ($safeResult === false) { + throw PcntlException::createFromPhpError(); + } +} + + /** * @param int|null $process_id * @return array @@ -200,3 +217,18 @@ function pcntl_sigwaitinfo(array $signals, ?array &$info = []): int } return $safeResult; } + + +/** + * @param int $flags + * @throws PcntlException + * + */ +function pcntl_unshare(int $flags): void +{ + error_clear_last(); + $safeResult = \pcntl_unshare($flags); + if ($safeResult === false) { + throw PcntlException::createFromPhpError(); + } +} diff --git a/generated/8.6/pgsql.php b/generated/8.6/pgsql.php index 10732a73..6f322df8 100644 --- a/generated/8.6/pgsql.php +++ b/generated/8.6/pgsql.php @@ -36,6 +36,24 @@ function pg_change_password(\PgSql\Connection $connection, string $user, string } +/** + * @param \PgSql\Connection $connection + * @param string $statement_name + * @return \PgSql\Result + * @throws PgsqlException + * + */ +function pg_close_stmt(\PgSql\Connection $connection, string $statement_name): \PgSql\Result +{ + error_clear_last(); + $safeResult = \pg_close_stmt($connection, $statement_name); + if ($safeResult === false) { + throw PgsqlException::createFromPhpError(); + } + return $safeResult; +} + + /** * @param string $connection_string * @param int $flags diff --git a/generated/8.6/rector-migrate.php b/generated/8.6/rector-migrate.php index 2d9ff12b..f6035d2d 100644 --- a/generated/8.6/rector-migrate.php +++ b/generated/8.6/rector-migrate.php @@ -652,6 +652,7 @@ 'parse_url' => 'Safe\parse_url', 'passthru' => 'Safe\passthru', 'pclose' => 'Safe\pclose', + 'pcntl_exec' => 'Safe\pcntl_exec', 'pcntl_getcpuaffinity' => 'Safe\pcntl_getcpuaffinity', 'pcntl_getpriority' => 'Safe\pcntl_getpriority', 'pcntl_setcpuaffinity' => 'Safe\pcntl_setcpuaffinity', @@ -662,9 +663,11 @@ 'pcntl_sigprocmask' => 'Safe\pcntl_sigprocmask', 'pcntl_sigtimedwait' => 'Safe\pcntl_sigtimedwait', 'pcntl_sigwaitinfo' => 'Safe\pcntl_sigwaitinfo', + 'pcntl_unshare' => 'Safe\pcntl_unshare', 'pfsockopen' => 'Safe\pfsockopen', 'pg_cancel_query' => 'Safe\pg_cancel_query', 'pg_change_password' => 'Safe\pg_change_password', + 'pg_close_stmt' => 'Safe\pg_close_stmt', 'pg_connect' => 'Safe\pg_connect', 'pg_connection_reset' => 'Safe\pg_connection_reset', 'pg_convert' => 'Safe\pg_convert', @@ -984,12 +987,14 @@ 'ssh2_exec' => 'Safe\ssh2_exec', 'ssh2_forward_accept' => 'Safe\ssh2_forward_accept', 'ssh2_forward_listen' => 'Safe\ssh2_forward_listen', + 'ssh2_keepalive_send' => 'Safe\ssh2_keepalive_send', 'ssh2_publickey_add' => 'Safe\ssh2_publickey_add', 'ssh2_publickey_init' => 'Safe\ssh2_publickey_init', 'ssh2_publickey_remove' => 'Safe\ssh2_publickey_remove', 'ssh2_scp_recv' => 'Safe\ssh2_scp_recv', 'ssh2_scp_send' => 'Safe\ssh2_scp_send', 'ssh2_send_eof' => 'Safe\ssh2_send_eof', + 'ssh2_send_signal' => 'Safe\ssh2_send_signal', 'ssh2_sftp' => 'Safe\ssh2_sftp', 'ssh2_sftp_chmod' => 'Safe\ssh2_sftp_chmod', 'ssh2_sftp_lstat' => 'Safe\ssh2_sftp_lstat', diff --git a/generated/8.6/ssh2.php b/generated/8.6/ssh2.php index d09d97a8..9ccecf1b 100644 --- a/generated/8.6/ssh2.php +++ b/generated/8.6/ssh2.php @@ -229,6 +229,23 @@ function ssh2_forward_listen($session, int $port, ?string $host = null, int $max } +/** + * @param resource $session + * @return int + * @throws Ssh2Exception + * + */ +function ssh2_keepalive_send($session): int +{ + error_clear_last(); + $safeResult = \ssh2_keepalive_send($session); + if ($safeResult === false) { + throw Ssh2Exception::createFromPhpError(); + } + return $safeResult; +} + + /** * @param resource $pkey * @param string $algoname @@ -336,6 +353,22 @@ function ssh2_send_eof($channel): void } +/** + * @param resource $channel + * @param string $signal + * @throws Ssh2Exception + * + */ +function ssh2_send_signal($channel, string $signal): void +{ + error_clear_last(); + $safeResult = \ssh2_send_signal($channel, $signal); + if ($safeResult === false) { + throw Ssh2Exception::createFromPhpError(); + } +} + + /** * @param resource $sftp * @param string $filename diff --git a/generator/src/XmlDocParser/DocPage.php b/generator/src/XmlDocParser/DocPage.php index 69d2255d..12c03d0a 100644 --- a/generator/src/XmlDocParser/DocPage.php +++ b/generator/src/XmlDocParser/DocPage.php @@ -8,7 +8,6 @@ use Safe\Generator\FileCreator; use function explode; -use function strpos; class DocPage { @@ -113,15 +112,19 @@ public function loadAndResolveFile(): \SimpleXMLElement } // Load entity definitions from .ent files and build entity replacement map - $entityReplacements = []; // Map of entity name => replacement value - + $entityReplacements = [ + 'false' => 'false', + 'true' => 'true', + 'null' => 'null', + ]; // Map of entity name => replacement value + // Load DTD-format entity files $patterns = [ '/php/doc-base/entities/*.ent', '/php/doc-en/*.ent', '/php/doc-en/entities/*.ent', ]; - + foreach ($patterns as $pattern) { $files = glob(PathHelper::docsDirectory() . $pattern); if ($files !== false) { @@ -130,7 +133,7 @@ public function loadAndResolveFile(): \SimpleXMLElement } } } - + // Also handle XML-format entity files (newer format) $xmlFiles = glob(PathHelper::docsDirectory() . '/php/doc-en/entities/*.ent'); if ($xmlFiles !== false) { @@ -155,6 +158,22 @@ public function loadAndResolveFile(): \SimpleXMLElement } } + // If php-base and php-en are out-of-sync, we get other undefined entities, + // let's strip those here + $content = (string)\preg_replace_callback( + '/&([a-zA-Z_][a-zA-Z0-9._-]*);/', + static function ($matches) { + $entity = $matches[1]; + // Preserve standard XML entities + if (\in_array($entity, ['lt', 'gt', 'amp', 'quot', 'apos'], true)) { + return $matches[0]; + } + // Render "undefined &url.mersenne;" as "url.mersenne" + return $entity; + }, + $content + ); + libxml_use_internal_errors(true); $elem = \simplexml_load_string($content, \SimpleXMLElement::class, LIBXML_DTDLOAD | LIBXML_NOENT); if ($elem === false) { @@ -182,20 +201,20 @@ private static function parseEntityFile(string $filePath, array &$entityReplacem if ($content === false) { return; } - + // Remove XML declaration and comments before wrapping in DOCTYPE $content = (string)\preg_replace('/<\?xml[^?]*\?>/', '', $content); $content = (string)\preg_replace('//', '', $content); - + // Wrap the entity declarations in a DOCTYPE so we can parse them // This allows libxml2 to properly parse the entity declarations $doctype = ''; $wrappedXml = '' . $doctype . ''; - + // Use DOMDocument to load the wrapped XML, which will parse the DTD entities $dom = new \DOMDocument('1.0', 'utf-8'); $dom->preserveWhiteSpace = true; - + libxml_use_internal_errors(true); if ($dom->loadXML($wrappedXml)) { // Get the internal DTD subset which contains the entity definitions @@ -207,7 +226,7 @@ private static function parseEntityFile(string $filePath, array &$entityReplacem } libxml_use_internal_errors(false); } - + /** * Extract entity definitions from a DTD internal subset string. * @@ -229,7 +248,7 @@ private static function extractEntitiesFromDtd(string $dtdSubset, array &$entity } } } - + /** * Parse XML-format entity file (newer PHP doc format). * These files contain ... elements. @@ -244,11 +263,11 @@ private static function parseXmlEntityFile(string $filePath, array &$entityRepla if ($content === false) { return; } - + // Remove XML declaration and comments $content = (string)\preg_replace('/<\?xml[^?]*\?>/', '', $content); $content = (string)\preg_replace('//', '', $content); - + // Extract entity elements using regex: ... // This avoids XML parsing issues with undefined entities if (\preg_match_all('/]*>([\s\S]*?)<\/entity>/s', $content, $matches, PREG_SET_ORDER)) {