1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-26 21:34:41 +01:00

Final fixes

This commit is contained in:
Daniil Gentili 2023-07-15 16:34:38 +02:00
parent e81f4be805
commit 6991133d50
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
10 changed files with 67 additions and 53 deletions

View File

@ -52,7 +52,7 @@ final class API extends AbstractAPI
* *
* @var string * @var string
*/ */
public const RELEASE = '8.0.0-beta99'; public const RELEASE = '8.0.0-beta100';
/** /**
* Secret chat was not found. * Secret chat was not found.
* *

View File

@ -317,8 +317,8 @@ final class Blacklist {
$contents .= " * @param {$psalmType} \${$name} {$description}\n"; $contents .= " * @param {$psalmType} \${$name} {$description}\n";
if ($name === 'entities') { if ($name === 'entities') {
$contents .= " * @param ''|'HTML'|'html'|'Markdown'|'markdown' \$parse_mode Whether to parse HTML or Markdown markup in the message\n"; $contents .= " * @param \\danog\\MadelineProto\\ParseMode \$parse_mode Whether to parse HTML or Markdown markup in the message\n";
$signature []= "string \$parse_mode = ''"; $signature []= "\\danog\\MadelineProto\\ParseMode \$parse_mode = \\danog\\MadelineProto\\ParseMode::TEXT";
} }
} }
return [$contents, $signature]; return [$contents, $signature];

View File

@ -1229,9 +1229,9 @@ abstract class InternalDoc
* *
* @see https://docs.madelineproto.xyz/API_docs/methods/messages.sendMessage.html#usage-of-parse_mode * @see https://docs.madelineproto.xyz/API_docs/methods/messages.sendMessage.html#usage-of-parse_mode
* *
* @return \danog\MadelineProto\TL\Conversion\DOMEntities Object containing message and entities * @return \danog\MadelineProto\TL\Conversion\MarkdownEntities Object containing message and entities
*/ */
public static function markdownToMessageEntities(string $markdown): \danog\MadelineProto\TL\Conversion\DOMEntities public static function markdownToMessageEntities(string $markdown): \danog\MadelineProto\TL\Conversion\MarkdownEntities
{ {
return \danog\MadelineProto\StrTools::markdownToMessageEntities($markdown); return \danog\MadelineProto\StrTools::markdownToMessageEntities($markdown);
} }

View File

@ -144,10 +144,10 @@ interface Help
* @param array|int|string $user_id User @see https://docs.madelineproto.xyz/API_docs/types/InputUser.html * @param array|int|string $user_id User @see https://docs.madelineproto.xyz/API_docs/types/InputUser.html
* @param string $message Message * @param string $message Message
* @param list<array{_: 'messageEntityUnknown', offset?: int, length?: int}|array{_: 'messageEntityMention', offset?: int, length?: int}|array{_: 'messageEntityHashtag', offset?: int, length?: int}|array{_: 'messageEntityBotCommand', offset?: int, length?: int}|array{_: 'messageEntityUrl', offset?: int, length?: int}|array{_: 'messageEntityEmail', offset?: int, length?: int}|array{_: 'messageEntityBold', offset?: int, length?: int}|array{_: 'messageEntityItalic', offset?: int, length?: int}|array{_: 'messageEntityCode', offset?: int, length?: int}|array{_: 'messageEntityPre', offset?: int, length?: int, language?: string}|array{_: 'messageEntityTextUrl', offset?: int, length?: int, url?: string}|array{_: 'messageEntityMentionName', offset?: int, length?: int, user_id?: int}|array{_: 'inputMessageEntityMentionName', user_id: array|int|string, offset?: int, length?: int}|array{_: 'messageEntityPhone', offset?: int, length?: int}|array{_: 'messageEntityCashtag', offset?: int, length?: int}|array{_: 'messageEntityUnderline', offset?: int, length?: int}|array{_: 'messageEntityStrike', offset?: int, length?: int}|array{_: 'messageEntityBlockquote', offset?: int, length?: int}|array{_: 'messageEntityBankCard', offset?: int, length?: int}|array{_: 'messageEntitySpoiler', offset?: int, length?: int}|array{_: 'messageEntityCustomEmoji', offset?: int, length?: int, document_id?: int}> $entities Array of [Message entities for styled text](https://core.telegram.org/api/entities) @see https://docs.madelineproto.xyz/API_docs/types/MessageEntity.html * @param list<array{_: 'messageEntityUnknown', offset?: int, length?: int}|array{_: 'messageEntityMention', offset?: int, length?: int}|array{_: 'messageEntityHashtag', offset?: int, length?: int}|array{_: 'messageEntityBotCommand', offset?: int, length?: int}|array{_: 'messageEntityUrl', offset?: int, length?: int}|array{_: 'messageEntityEmail', offset?: int, length?: int}|array{_: 'messageEntityBold', offset?: int, length?: int}|array{_: 'messageEntityItalic', offset?: int, length?: int}|array{_: 'messageEntityCode', offset?: int, length?: int}|array{_: 'messageEntityPre', offset?: int, length?: int, language?: string}|array{_: 'messageEntityTextUrl', offset?: int, length?: int, url?: string}|array{_: 'messageEntityMentionName', offset?: int, length?: int, user_id?: int}|array{_: 'inputMessageEntityMentionName', user_id: array|int|string, offset?: int, length?: int}|array{_: 'messageEntityPhone', offset?: int, length?: int}|array{_: 'messageEntityCashtag', offset?: int, length?: int}|array{_: 'messageEntityUnderline', offset?: int, length?: int}|array{_: 'messageEntityStrike', offset?: int, length?: int}|array{_: 'messageEntityBlockquote', offset?: int, length?: int}|array{_: 'messageEntityBankCard', offset?: int, length?: int}|array{_: 'messageEntitySpoiler', offset?: int, length?: int}|array{_: 'messageEntityCustomEmoji', offset?: int, length?: int, document_id?: int}> $entities Array of [Message entities for styled text](https://core.telegram.org/api/entities) @see https://docs.madelineproto.xyz/API_docs/types/MessageEntity.html
* @param ''|'HTML'|'html'|'Markdown'|'markdown' $parse_mode Whether to parse HTML or Markdown markup in the message * @param \danog\MadelineProto\ParseMode $parse_mode Whether to parse HTML or Markdown markup in the message
* @return array{_: 'help.userInfoEmpty'}|array{_: 'help.userInfo', message: string, entities: list<array{_: 'messageEntityUnknown', offset: int, length: int}|array{_: 'messageEntityMention', offset: int, length: int}|array{_: 'messageEntityHashtag', offset: int, length: int}|array{_: 'messageEntityBotCommand', offset: int, length: int}|array{_: 'messageEntityUrl', offset: int, length: int}|array{_: 'messageEntityEmail', offset: int, length: int}|array{_: 'messageEntityBold', offset: int, length: int}|array{_: 'messageEntityItalic', offset: int, length: int}|array{_: 'messageEntityCode', offset: int, length: int}|array{_: 'messageEntityPre', offset: int, length: int, language: string}|array{_: 'messageEntityTextUrl', offset: int, length: int, url: string}|array{_: 'messageEntityMentionName', offset: int, length: int, user_id: int}|array{_: 'inputMessageEntityMentionName', user_id: array|int|string, offset: int, length: int}|array{_: 'messageEntityPhone', offset: int, length: int}|array{_: 'messageEntityCashtag', offset: int, length: int}|array{_: 'messageEntityUnderline', offset: int, length: int}|array{_: 'messageEntityStrike', offset: int, length: int}|array{_: 'messageEntityBlockquote', offset: int, length: int}|array{_: 'messageEntityBankCard', offset: int, length: int}|array{_: 'messageEntitySpoiler', offset: int, length: int}|array{_: 'messageEntityCustomEmoji', offset: int, length: int, document_id: int}>, author: string, date: int} @see https://docs.madelineproto.xyz/API_docs/types/help.UserInfo.html * @return array{_: 'help.userInfoEmpty'}|array{_: 'help.userInfo', message: string, entities: list<array{_: 'messageEntityUnknown', offset: int, length: int}|array{_: 'messageEntityMention', offset: int, length: int}|array{_: 'messageEntityHashtag', offset: int, length: int}|array{_: 'messageEntityBotCommand', offset: int, length: int}|array{_: 'messageEntityUrl', offset: int, length: int}|array{_: 'messageEntityEmail', offset: int, length: int}|array{_: 'messageEntityBold', offset: int, length: int}|array{_: 'messageEntityItalic', offset: int, length: int}|array{_: 'messageEntityCode', offset: int, length: int}|array{_: 'messageEntityPre', offset: int, length: int, language: string}|array{_: 'messageEntityTextUrl', offset: int, length: int, url: string}|array{_: 'messageEntityMentionName', offset: int, length: int, user_id: int}|array{_: 'inputMessageEntityMentionName', user_id: array|int|string, offset: int, length: int}|array{_: 'messageEntityPhone', offset: int, length: int}|array{_: 'messageEntityCashtag', offset: int, length: int}|array{_: 'messageEntityUnderline', offset: int, length: int}|array{_: 'messageEntityStrike', offset: int, length: int}|array{_: 'messageEntityBlockquote', offset: int, length: int}|array{_: 'messageEntityBankCard', offset: int, length: int}|array{_: 'messageEntitySpoiler', offset: int, length: int}|array{_: 'messageEntityCustomEmoji', offset: int, length: int, document_id: int}>, author: string, date: int} @see https://docs.madelineproto.xyz/API_docs/types/help.UserInfo.html
*/ */
public function editUserInfo(array|int|string $user_id, string $message = '', array $entities = [], string $parse_mode = ''): array; public function editUserInfo(array|int|string $user_id, string $message = '', array $entities = [], \danog\MadelineProto\ParseMode $parse_mode = \danog\MadelineProto\ParseMode::TEXT): array;
/** /**
* Get MTProxy/Public Service Announcement information. * Get MTProxy/Public Service Announcement information.

File diff suppressed because one or more lines are too long

View File

@ -23,7 +23,7 @@ namespace danog\MadelineProto;
use danog\MadelineProto\TL\Conversion\DOMEntities; use danog\MadelineProto\TL\Conversion\DOMEntities;
use danog\MadelineProto\TL\Conversion\Extension; use danog\MadelineProto\TL\Conversion\Extension;
use danog\MadelineProto\TL\Conversion\MarkdownEntities; use danog\MadelineProto\TL\Conversion\MarkdownEntities;
use Parsedown; use Throwable;
use Webmozart\Assert\Assert; use Webmozart\Assert\Assert;
/** /**
@ -236,6 +236,10 @@ abstract class StrTools extends Extension
if ($markdown === '') { if ($markdown === '') {
return $markdown; return $markdown;
} }
return (new DOMEntities(Parsedown::instance()->text($markdown)))->message; try {
return (new MarkdownEntities($markdown))->message;
} catch (Throwable) {
return (new MarkdownEntities(\str_replace('_', '\\_', $markdown)))->message;
}
} }
} }

View File

@ -26,7 +26,6 @@ use danog\MadelineProto\Logger;
use danog\MadelineProto\MTProto; use danog\MadelineProto\MTProto;
use danog\MadelineProto\StrTools; use danog\MadelineProto\StrTools;
use danog\MadelineProto\Tools; use danog\MadelineProto\Tools;
use Parsedown;
use Throwable; use Throwable;
use const danog\Decoder\TYPES_IDS; use const danog\Decoder\TYPES_IDS;
@ -503,7 +502,7 @@ trait BotAPI
$offset += $entity['length']; $offset += $entity['length'];
$newentity['offset'] = $offset; $newentity['offset'] = $offset;
$orig = $multiple_args[$i]['message']; $orig = $multiple_args[$i]['message'];
$trimmed = rtrim($orig); $trimmed = \rtrim($orig);
$diff = StrTools::mbStrlen($orig) - StrTools::mbStrlen($trimmed); $diff = StrTools::mbStrlen($orig) - StrTools::mbStrlen($trimmed);
$entity['length'] -= $diff; $entity['length'] -= $diff;
$multiple_args[$i]['message'] = $trimmed; $multiple_args[$i]['message'] = $trimmed;

View File

@ -4,14 +4,6 @@ declare(strict_types=1);
namespace danog\MadelineProto\TL\Conversion; namespace danog\MadelineProto\TL\Conversion;
use danog\MadelineProto\Exception;
use danog\MadelineProto\StrTools;
use DOMDocument;
use DOMElement;
use DOMNode;
use DOMText;
use Throwable;
/** /**
* Class that converts HTML or markdown to a message + set of entities. * Class that converts HTML or markdown to a message + set of entities.
* *

View File

@ -7,10 +7,6 @@ namespace danog\MadelineProto\TL\Conversion;
use AssertionError; use AssertionError;
use danog\MadelineProto\Exception; use danog\MadelineProto\Exception;
use danog\MadelineProto\StrTools; use danog\MadelineProto\StrTools;
use DOMDocument;
use DOMElement;
use DOMNode;
use DOMText;
use Throwable; use Throwable;
/** /**
@ -28,18 +24,18 @@ final class MarkdownEntities extends Entities
*/ */
public function __construct(string $markdown) public function __construct(string $markdown)
{ {
$markdown = str_replace("\r\n", "\n", $markdown); $markdown = \str_replace("\r\n", "\n", $markdown);
try { try {
$message = ''; $message = '';
$messageLen = 0; $messageLen = 0;
$entities = []; $entities = [];
$offset = 0; $offset = 0;
$stack = []; $stack = [];
while ($offset < strlen($markdown)) { while ($offset < \strlen($markdown)) {
$len = strcspn($markdown, '*_~`[]|\\', $offset); $len = \strcspn($markdown, '*_~`[]|!\\', $offset);
$piece = substr($markdown, $offset, $len); $piece = \substr($markdown, $offset, $len);
$offset += $len; $offset += $len;
if ($offset === strlen($markdown)) { if ($offset === \strlen($markdown)) {
$message .= $piece; $message .= $piece;
break; break;
} }
@ -65,10 +61,19 @@ final class MarkdownEntities extends Entities
$messageLen += StrTools::mbStrlen($piece)+1; $messageLen += StrTools::mbStrlen($piece)+1;
continue; continue;
} }
} elseif ($char === '!') {
if ($next === '[') {
$offset++;
$char = '](';
} else {
$message .= $piece.$char;
$messageLen += StrTools::mbStrlen($piece)+1;
continue;
}
} elseif ($char === '[') { } elseif ($char === '[') {
$char = ']('; $char = '](';
} elseif ($char === ']') { } elseif ($char === ']') {
if (!$stack || end($stack)[0] !== '](') { if (!$stack || \end($stack)[0] !== '](') {
$message .= $piece.$char; $message .= $piece.$char;
$messageLen += StrTools::mbStrlen($piece)+1; $messageLen += StrTools::mbStrlen($piece)+1;
continue; continue;
@ -83,15 +88,15 @@ final class MarkdownEntities extends Entities
$messageLen += StrTools::mbStrlen($piece); $messageLen += StrTools::mbStrlen($piece);
$offset += 2; $offset += 2;
$langLen = strcspn($markdown, "\n ", $offset); $langLen = \strcspn($markdown, "\n ", $offset);
$language = substr($markdown, $offset, $langLen); $language = \substr($markdown, $offset, $langLen);
$offset += $langLen; $offset += $langLen;
if ($markdown[$offset] === "\n") { if ($markdown[$offset] === "\n") {
$offset++; $offset++;
} }
$posClose = $offset; $posClose = $offset;
while (($posClose = strpos($markdown, '```', $posClose)) !== false) { while (($posClose = \strpos($markdown, '```', $posClose)) !== false) {
if ($markdown[$posClose-1] === '\\') { if ($markdown[$posClose-1] === '\\') {
$posClose++; $posClose++;
continue; continue;
@ -104,7 +109,7 @@ final class MarkdownEntities extends Entities
$start = $messageLen; $start = $messageLen;
$message .= $piece = substr($markdown, $offset, $posClose-$offset); $message .= $piece = \substr($markdown, $offset, $posClose-$offset);
$pieceLen = StrTools::mbStrlen($piece); $pieceLen = StrTools::mbStrlen($piece);
$messageLen += $pieceLen; $messageLen += $pieceLen;
@ -131,11 +136,11 @@ final class MarkdownEntities extends Entities
continue; continue;
} }
if ($stack && end($stack)[0] === $char) { if ($stack && \end($stack)[0] === $char) {
[, $start] = array_pop($stack); [, $start] = \array_pop($stack);
if ($char === '](') { if ($char === '](') {
$posClose = $offset; $posClose = $offset;
while (($posClose = strpos($markdown, ')', $posClose)) !== false) { while (($posClose = \strpos($markdown, ')', $posClose)) !== false) {
if ($markdown[$posClose-1] === '\\') { if ($markdown[$posClose-1] === '\\') {
$posClose++; $posClose++;
continue; continue;
@ -145,7 +150,7 @@ final class MarkdownEntities extends Entities
if ($posClose === false) { if ($posClose === false) {
throw new AssertionError("Unclosed ) opened @ pos $offset!"); throw new AssertionError("Unclosed ) opened @ pos $offset!");
} }
$entity = self::handleLink(substr($markdown, $offset, $posClose-$offset)); $entity = self::handleLink(\substr($markdown, $offset, $posClose-$offset));
$offset = $posClose+1; $offset = $posClose+1;
} else { } else {
$entity = match ($char) { $entity = match ($char) {
@ -162,7 +167,7 @@ final class MarkdownEntities extends Entities
$messageLen += StrTools::mbStrlen($piece); $messageLen += StrTools::mbStrlen($piece);
$lengthReal = $messageLen-$start; $lengthReal = $messageLen-$start;
for ($x = strlen($message)-1; $x >= 0; $x--) { for ($x = \strlen($message)-1; $x >= 0; $x--) {
if (!( if (!(
$message[$x] === ' ' $message[$x] === ' '
|| $message[$x] === "\r" || $message[$x] === "\r"
@ -181,6 +186,9 @@ final class MarkdownEntities extends Entities
$stack []= [$char, $messageLen]; $stack []= [$char, $messageLen];
} }
} }
if ($stack) {
throw new AssertionError("Found unclosed markdown elements ".\implode(', ', \array_column($stack, 0)));
}
$this->message = $message; $this->message = $message;
$this->entities = $entities; $this->entities = $entities;

View File

@ -27,6 +27,7 @@ use Closure;
use Countable; use Countable;
use Exception; use Exception;
use Fiber; use Fiber;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Include_; use PhpParser\Node\Expr\Include_;
use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\New_;
@ -600,7 +601,7 @@ abstract class Tools extends AsyncTools
private const BANNED_FUNCTIONS = [ private const BANNED_FUNCTIONS = [
'file_get_contents' => 'please use https://github.com/amphp/file or https://github.com/amphp/http-client, instead', 'file_get_contents' => 'please use https://github.com/amphp/file or https://github.com/amphp/http-client, instead',
'file_put_contents' => 'please use https://github.com/amphp/file, instead', 'file_put_contents' => 'please use https://github.com/amphp/file, instead',
'unlink' => 'please use https://github.com/amphp/http-client, instead', 'unlink' => 'plugins may not access the filesystem',
'curl_exec' => 'please use https://github.com/amphp/http-client, instead', 'curl_exec' => 'please use https://github.com/amphp/http-client, instead',
'mysqli_query' => 'please use https://github.com/amphp/mysql, instead', 'mysqli_query' => 'please use https://github.com/amphp/mysql, instead',
'mysqli_connect' => 'please use https://github.com/amphp/mysql, instead', 'mysqli_connect' => 'please use https://github.com/amphp/mysql, instead',
@ -662,6 +663,16 @@ abstract class Tools extends AsyncTools
$name = $call->name->toLowerString(); $name = $call->name->toLowerString();
if (isset(self::BANNED_FUNCTIONS[$name])) { if (isset(self::BANNED_FUNCTIONS[$name])) {
if (!$plugin && $name === 'unlink') {
if ($call->args
&& $call->args[0] instanceof Arg
&& $call->args[0]->value instanceof String_
&& $call->args[0]->value->value === 'MadelineProto.log'
) {
throw new AssertionError("An error occurred while analyzing $class: the MadelineProto.log must never be deleted, please set a custom max size in the settings, instead!");
}
continue;
}
$explanation = self::BANNED_FUNCTIONS[$name]; $explanation = self::BANNED_FUNCTIONS[$name];
throw new AssertionError("An error occurred while analyzing $class: for performance reasons, plugins may not use the non-async blocking function $name, $explanation!"); throw new AssertionError("An error occurred while analyzing $class: for performance reasons, plugins may not use the non-async blocking function $name, $explanation!");
} }