1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 04:08:59 +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
*/
public const RELEASE = '8.0.0-beta99';
public const RELEASE = '8.0.0-beta100';
/**
* Secret chat was not found.
*

View File

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

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 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 ''|'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
*/
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.

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\Extension;
use danog\MadelineProto\TL\Conversion\MarkdownEntities;
use Parsedown;
use Throwable;
use Webmozart\Assert\Assert;
/**
@ -236,6 +236,10 @@ abstract class StrTools extends Extension
if ($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\StrTools;
use danog\MadelineProto\Tools;
use Parsedown;
use Throwable;
use const danog\Decoder\TYPES_IDS;
@ -503,7 +502,7 @@ trait BotAPI
$offset += $entity['length'];
$newentity['offset'] = $offset;
$orig = $multiple_args[$i]['message'];
$trimmed = rtrim($orig);
$trimmed = \rtrim($orig);
$diff = StrTools::mbStrlen($orig) - StrTools::mbStrlen($trimmed);
$entity['length'] -= $diff;
$multiple_args[$i]['message'] = $trimmed;

View File

@ -4,14 +4,6 @@ declare(strict_types=1);
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.
*

View File

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

View File

@ -27,6 +27,7 @@ use Closure;
use Countable;
use Exception;
use Fiber;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Include_;
use PhpParser\Node\Expr\New_;
@ -600,7 +601,7 @@ abstract class Tools extends AsyncTools
private const BANNED_FUNCTIONS = [
'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',
'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',
'mysqli_query' => '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();
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];
throw new AssertionError("An error occurred while analyzing $class: for performance reasons, plugins may not use the non-async blocking function $name, $explanation!");
}