This commit is contained in:
Daniil Gentili 2021-08-14 15:49:52 +02:00
parent 1394bbdc11
commit cd57194072
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
10 changed files with 427 additions and 98 deletions

View File

@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
tag: ["amd64"]
php: ["7.0", "7.1", "7.2", "7.3", "7.4"]
php: ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0"]
name: PHP ${{ matrix.php }} Test on ${{ matrix.tag }}
steps:
- name: Checkout

View File

@ -21,6 +21,7 @@ namespace danog\Decoder;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceDialogPhoto;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceLegacy;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceStickersetThumbnail;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceStickersetThumbnailVersion;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceThumbnail;
/**
@ -137,30 +138,43 @@ class FileId
$result->setId($resultArray['id']);
if ($result->getType() <= PHOTO) {
$result->setVolumeId($resultArray['volume_id']);
$result->setLocalId($resultArray['local_id']);
if (isset($resultArray['volume_id'])) {
$result->setVolumeId($resultArray['volume_id']);
}
if (isset($resultArray['local_id'])) {
$result->setLocalId($resultArray['local_id']);
}
switch ($resultArray['photosize_source']) {
case PHOTOSIZE_SOURCE_LEGACY:
$photoSizeSource = new PhotoSizeSourceLegacy;
case PHOTOSIZE_SOURCE_FULL_LEGACY:
$photoSizeSource = new PhotoSizeSourceLegacy($resultArray['photosize_source']);
$photoSizeSource->setSecret($resultArray['secret']);
break;
case PHOTOSIZE_SOURCE_THUMBNAIL:
$photoSizeSource = new PhotoSizeSourceThumbnail;
$photoSizeSource = new PhotoSizeSourceThumbnail($resultArray['photosize_source']);
$photoSizeSource->setThumbType($resultArray['thumbnail_type']);
$photoSizeSource->setThumbFileType($resultArray['file_type']);
break;
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
$photoSizeSource = new PhotoSizeSourceDialogPhoto;
$photoSizeSource->setDialogPhotoSmall($resultArray['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL);
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
$photoSizeSource = new PhotoSizeSourceDialogPhoto($resultArray['photosize_source']);
$photoSizeSource->setDialogId($resultArray['dialog_id']);
$photoSizeSource->setDialogAccessHash($resultArray['dialog_access_hash']);
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
$photoSizeSource = new PhotoSizeSourceStickersetThumbnail;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
$photoSizeSource = new PhotoSizeSourceStickersetThumbnail($resultArray['photosize_source']);
$photoSizeSource->setStickerSetId($resultArray['sticker_set_id']);
$photoSizeSource->setStickerSetAccessHash($resultArray['sticker_set_access_hash']);
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
$photoSizeSource = new PhotoSizeSourceStickersetThumbnailVersion($resultArray['photosize_source']);
$photoSizeSource->setStickerSetId($resultArray['sticker_set_id']);
$photoSizeSource->setStickerSetAccessHash($resultArray['sticker_set_access_hash']);
$photoSizeSource->setStickerSetVersion($resultArray['sticker_version']);
break;
}
$result->setPhotoSizeSource($photoSizeSource);
}
@ -198,29 +212,42 @@ class FileId
$fileId .= packLong($this->getAccessHash());
if ($this->getType() <= PHOTO) {
$fileId .= packLong($this->getVolumeId());
$photoSize = $this->getPhotoSizeSource();
if ($this->getVersion() >= 4) {
$fileId .= \pack('V', $photoSize->getType());
}
$fileId .= \pack('V', $photoSize->getType());
switch ($photoSize->getType()) {
case PHOTOSIZE_SOURCE_LEGACY:
$fileId .= packLong($photoSize->getSecret());
break;
case PHOTOSIZE_SOURCE_FULL_LEGACY:
$fileId .= packLong($this->getVolumeId());
$fileId .= packLong($photoSize->getSecret());
$fileId .= pack('l',$this->getLocalId());
break;
case PHOTOSIZE_SOURCE_THUMBNAIL:
$fileId .= \pack('Va4', $photoSize->getThumbFileType(), $photoSize->getThumbType());
break;
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
$fileId .= packLongBig($photoSize->getDialogId());
$fileId .= packLong($photoSize->getDialogAccessHash());
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
$fileId .= packLong($photoSize->getStickerSetId());
$fileId .= packLong($photoSize->getStickerSetAccessHash());
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
$fileId .= packLong($photoSize->getStickerSetId());
$fileId .= packLong($photoSize->getStickerSetAccessHash());
$fileId .= pack('l', $photoSize->getStickerSetVersion());
break;
}
if ($photoSize->getType() >= PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY && $photoSize->getType() <= PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY) {
$fileId .= packLong($this->getVolumeId());
$fileId .= \pack('l', $this->getLocalId());
}
$fileId .= \pack('l', $this->getLocalId());
}
if ($this->getVersion() >= 4) {

View File

@ -35,13 +35,11 @@ abstract class PhotoSizeSource
private $_type;
/**
* Get photosize source type.
* Set photosize source type.
*
* @param integer $type Type
*
* @return self
*/
public function setType(int $type): self
public function __construct(int $type)
{
$this->_type = $type;

View File

@ -22,6 +22,7 @@ use danog\Decoder\PhotoSizeSource;
use const danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG;
use const danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL;
use const danog\Decoder\PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY;
/**
* Represents source of photosize.
@ -43,14 +44,6 @@ class PhotoSizeSourceDialogPhoto extends PhotoSizeSource
*/
private $_dialogAccessHash;
/**
* Constructor.
*/
public function __construct()
{
$this->setType(PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG);
}
/**
* Get dialog ID.
*
@ -103,18 +96,6 @@ class PhotoSizeSourceDialogPhoto extends PhotoSizeSource
*/
public function isSmallDialogPhoto(): bool
{
return $this->getType() === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL;
}
/**
* Set whether the big or small version of the photo is being used.
*
* @param bool $_dialogPhotoSmall Whether the big or small version of the photo is being used
*
* @return self
*/
public function setDialogPhotoSmall(bool $_dialogPhotoSmall): self
{
return $this->setType($_dialogPhotoSmall ? PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL : PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG);
return in_array($this->getType(), [PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY, PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL]);
}
}

View File

@ -20,8 +20,6 @@ namespace danog\Decoder\PhotoSizeSource;
use danog\Decoder\PhotoSizeSource;
use const danog\Decoder\PHOTOSIZE_SOURCE_LEGACY;
/**
* Represents source of photosize.
*
@ -29,13 +27,6 @@ use const danog\Decoder\PHOTOSIZE_SOURCE_LEGACY;
*/
class PhotoSizeSourceLegacy extends PhotoSizeSource
{
/**
* Constructor.
*/
public function __construct()
{
$this->setType(PHOTOSIZE_SOURCE_LEGACY);
}
/**
* Secret legacy ID.
*

View File

@ -20,8 +20,6 @@ namespace danog\Decoder\PhotoSizeSource;
use danog\Decoder\PhotoSizeSource;
use const danog\Decoder\PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL;
/**
* Represents source of photosize.
*
@ -29,13 +27,6 @@ use const danog\Decoder\PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL;
*/
class PhotoSizeSourceStickersetThumbnail extends PhotoSizeSource
{
/**
* Constructor.
*/
public function __construct()
{
$this->setType(PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL);
}
/**
* Stickerset ID.
*

View File

@ -0,0 +1,121 @@
<?php
/**
* Photosize source class.
*
* This file is part of tg-file-decoder.
* tg-file-decoder is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* tg-file-decoder is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with tg-file-decoder.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
*
* @link https://github.com/tg-file-decoder Documentation
*/
namespace danog\Decoder\PhotoSizeSource;
use danog\Decoder\PhotoSizeSource;
/**
* Represents source of photosize.
*
* @extends PhotoSizeSource<PhotoSizeSourceStickersetThumbnailVersion>
*/
class PhotoSizeSourceStickersetThumbnailVersion extends PhotoSizeSource
{
/**
* Stickerset ID.
*
* @var int
*/
private $_stickerSetId;
/**
* Stickerset access hash.
*
* @var int
*/
private $_stickerSetAccessHash;
/**
* Stickerset version.
*
* @var int
*/
private $_stickerSetVersion;
/**
* Get stickerset ID.
*
* @return int
*/
public function getStickerSetId()
{
return $this->_stickerSetId;
}
/**
* Set stickerset ID.
*
* @param int $_stickerSetId Stickerset ID
*
* @return self
*/
public function setStickerSetId($_stickerSetId): self
{
$this->_stickerSetId = $_stickerSetId;
return $this;
}
/**
* Get stickerset access hash.
*
* @return int
*/
public function getStickerSetAccessHash()
{
return $this->_stickerSetAccessHash;
}
/**
* Set stickerset access hash.
*
* @param int $_stickerSetAccessHash Stickerset access hash
*
* @return self
*/
public function setStickerSetAccessHash($_stickerSetAccessHash): self
{
$this->_stickerSetAccessHash = $_stickerSetAccessHash;
return $this;
}
/**
* Get stickerset version.
*
* @return int
*/
public function getStickerSetVersion(): int
{
return $this->_stickerSetVersion;
}
/**
* Set stickerset version.
*
* @param int $_stickerSetVersion Stickerset version.
*
* @return self
*/
public function setStickerSetVersion(int $_stickerSetVersion): self
{
$this->_stickerSetVersion = $_stickerSetVersion;
return $this;
}
}

View File

@ -20,7 +20,6 @@ namespace danog\Decoder\PhotoSizeSource;
use danog\Decoder\PhotoSizeSource;
use const danog\Decoder\PHOTOSIZE_SOURCE_THUMBNAIL;
use const danog\Decoder\TYPES;
/**
@ -28,13 +27,6 @@ use const danog\Decoder\TYPES;
*/
class PhotoSizeSourceThumbnail extends PhotoSizeSource
{
/**
* Constructor.
*/
public function __construct()
{
$this->setType(PHOTOSIZE_SOURCE_THUMBNAIL);
}
/**
* File type of original file.
*

View File

@ -18,6 +18,10 @@
namespace danog\Decoder;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceDialogPhoto;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceStickersetThumbnailVersion;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceThumbnail;
/**
* Represents decoded unique bot API file ID.
*/
@ -47,6 +51,24 @@ class UniqueFileId
* @var int
*/
private $_localId;
/**
* Photo subtype
*
* @var int
*/
private $_subType;
/**
* Sticker set ID
*
* @var int
*/
private $_stickerSetId;
/**
* Sticker set version
*
* @var int
*/
private $_stickerSetVersion;
/**
* Weblocation URL.
*
@ -81,8 +103,17 @@ class UniqueFileId
if ($this->getType() === UNIQUE_WEB) {
$fileId .= packTLString($this->getUrl());
} elseif ($this->getType() === UNIQUE_PHOTO) {
$fileId .= packLong($this->getVolumeId());
$fileId .= \pack('l', $this->getLocalId());
if ($this->hasVolumeId()) {
$fileId .= packLong($this->getVolumeId());
$fileId .= \pack('l', $this->getLocalId());
} elseif ($this->hasStickerSetId()) {
$fileId .= chr($this->getSubType());
$fileId .= packLong($this->getStickerSetId());
$fileId .= pack('l', $this->getStickerSetVersion());
} else {
$fileId .= packLong($this->getId());
$fileId .= chr($this->getSubType());
}
} elseif ($this->hasId()) {
$fileId .= packLong($this->getId());
}
@ -105,8 +136,17 @@ class UniqueFileId
if ($result->getType() === UNIQUE_WEB) {
$result->setUrl($resultArray['url']);
} elseif ($result->getType() === UNIQUE_PHOTO) {
$result->setVolumeId($resultArray['volume_id']);
$result->setLocalId($resultArray['local_id']);
if (isset($resultArray['volume_id'])) {
$result->setVolumeId($resultArray['volume_id']);
$result->setLocalId($resultArray['local_id']);
} else if (isset($resultArray['id'])) {
$result->setId($resultArray['id']);
$result->setSubType($resultArray['subType']);
} else if (isset($resultArray['sticker_set_id'])) {
$result->setStickerSetId($resultArray['sticker_set_id']);
$result->setStickerSetVersion($resultArray['sticker_set_version']);
$result->setSubType($resultArray['subType']);
}
} elseif (isset($resultArray['id'])) {
$result->setId($resultArray['id']);
}
@ -143,8 +183,30 @@ class UniqueFileId
if ($result->getType() === UNIQUE_WEB) {
$result->setUrl($fileId->getUrl());
} elseif ($result->getType() === UNIQUE_PHOTO) {
$result->setVolumeId($fileId->getVolumeId());
$result->setLocalId($fileId->getLocalId());
if ($fileId->hasVolumeId()) {
$result->setVolumeId($fileId->getVolumeId());
$result->setLocalId($fileId->getLocalId());
} else if ($fileId->hasId()) {
$result->setId($fileId->getId());
$photoSize = $fileId->getPhotoSizeSource();
if ($photoSize instanceof PhotoSizeSourceThumbnail) {
$type = $photoSize->getThumbType();
if ($type === 'a') {
$type = chr(0);
} else if ($type === 'c') {
$type = chr(1);
} else {
$type = chr(ord($type)+5);
}
$result->setSubType(ord($type));
} else if ($photoSize instanceof PhotoSizeSourceDialogPhoto) {
$result->setSubType($photoSize->isSmallDialogPhoto() ? 0 : 1);
} else if ($photoSize instanceof PhotoSizeSourceStickersetThumbnailVersion) {
$result->setSubType(2);
$result->setStickerSetId($photoSize->getStickerSetId());
$result->setStickerSetVersion($photoSize->getStickerSetVersion());
}
}
} elseif ($fileId->hasId()) {
$result->setId($fileId->getId());
}
@ -322,4 +384,107 @@ class UniqueFileId
{
return isset($this->_url);
}
/**
* Get photo subtype
*
* @return int
*/
public function getSubType(): int
{
return $this->_subType;
}
/**
* Has photo subtype?
*
* @return bool
*/
public function hasSubType(): bool
{
return isset($this->_subType);
}
/**
* Set photo subtype
*
* @param int $_subType Photo subtype
*
* @return self
*/
public function setSubType(int $_subType): self
{
$this->_subType = $_subType;
return $this;
}
/**
* Get sticker set ID
*
* @return int
*/
public function getStickerSetId()
{
return $this->_stickerSetId;
}
/**
* Has sticker set ID?
*
* @return bool
*/
public function hasStickerSetId(): bool
{
return isset($this->_stickerSetId);
}
/**
* Set sticker set ID
*
* @param int $_stickerSetId Sticker set ID
*
* @return self
*/
public function setStickerSetId($_stickerSetId): self
{
$this->_stickerSetId = $_stickerSetId;
return $this;
}
/**
* Get sticker set version
*
* @return int
*/
public function getStickerSetVersion(): int
{
return $this->_stickerSetVersion;
}
/**
* Has sticker set version
*
* @return bool
*/
public function hasStickerSetVersion(): bool
{
return isset($this->_stickerSetVersion);
}
/**
* Set sticker set version
*
* @param int $_stickerSetVersion Sticker set version
*
* @return self
*/
public function setStickerSetVersion(int $_stickerSetVersion): self
{
$this->_stickerSetVersion = $_stickerSetVersion;
return $this;
}
}

View File

@ -189,6 +189,11 @@ const PHOTOSIZE_SOURCE_THUMBNAIL = 1;
const PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL = 2;
const PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG = 3;
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL = 4;
const PHOTOSIZE_SOURCE_FULL_LEGACY = 5;
const PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY = 6;
const PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY = 7;
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY = 8;
const PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION = 9;
const WEB_LOCATION_FLAG = 1 << 24;
const FILE_REFERENCE_FLAG = 1 << 25;
@ -492,33 +497,75 @@ function internalDecode(string $fileId): array
fixLong($result, 'access_hash');
if ($result['typeId'] <= PHOTO) {
$result += \unpack(LONG.'volume_id', \stream_get_contents($fileId, 8));
fixLong($result, 'volume_id');
$result['secret'] = 0;
$result['photosize_source'] = $result['version'] >= 4 ? \unpack('V', \stream_get_contents($fileId, 4))[1] : 0;
// Legacy, Thumbnail, DialogPhotoSmall, DialogPhotoBig, StickerSetThumbnail
switch ($result['photosize_source']) {
case PHOTOSIZE_SOURCE_LEGACY:
$result += \unpack(LONG.'secret', \stream_get_contents($fileId, 8));
$parsePhotoSize = function () use (&$result, &$fileId): void {
$result['photosize_source'] = $result['subVersion'] >= 4 ? \unpack('V', \stream_get_contents($fileId, 4))[1] : 0;
switch ($result['photosize_source']) {
case PHOTOSIZE_SOURCE_LEGACY:
$result += \unpack(LONG.'secret', \stream_get_contents($fileId, 8));
fixLong($result, 'secret');
break;
case PHOTOSIZE_SOURCE_THUMBNAIL:
$result += \unpack('Vfile_type/athumbnail_type', \stream_get_contents($fileId, 8));
break;
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
$result['photo_size'] = $result['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL ? 'photo_small' : 'photo_big';
$result['dialog_id'] = unpackLong(\stream_get_contents($fileId, 8));
$result['dialog_access_hash'] = \unpack(LONG, \stream_get_contents($fileId, 8))[1];
fixLong($result, 'dialog_access_hash');
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash', \stream_get_contents($fileId, 16));
fixLong($result, 'sticker_set_id');
fixLong($result, 'sticker_set_access_hash');
break;
case PHOTOSIZE_SOURCE_FULL_LEGACY:
$result += \unpack(LONG.'volume_id/'.LONG.'secret/llocal_id', \stream_get_contents($fileId, 20));
fixLong($result, 'volume_id');
fixLong($result, 'secret');
break;
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG_LEGACY:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY:
$result['photo_size'] = $result['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL_LEGACY ? 'photo_small' : 'photo_big';
$result['dialog_id'] = unpackLong(\stream_get_contents($fileId, 8));
$result['dialog_access_hash'] = \unpack(LONG, \stream_get_contents($fileId, 8))[1];
fixLong($result, 'dialog_access_hash');
$result += \unpack(LONG.'volume_id/llocal_id', \stream_get_contents($fileId, 12));
fixLong($result, 'volume_id');
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_LEGACY:
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash', \stream_get_contents($fileId, 16));
fixLong($result, 'sticker_set_id');
fixLong($result, 'sticker_set_access_hash');
$result += \unpack(LONG.'volume_id/llocal_id', \stream_get_contents($fileId, 12));
fixLong($result, 'volume_id');
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL_VERSION:
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash/lsticker_version', \stream_get_contents($fileId, 20));
fixLong($result, 'sticker_set_id');
fixLong($result, 'sticker_set_access_hash');
break;
}
};
if ($result['subVersion'] >= 32) {
$parsePhotoSize();
} else {
$result += \unpack(LONG.'volume_id', \stream_get_contents($fileId, 8));
fixLong($result, 'volume_id');
if ($result['subVersion'] >= 22) {
$parsePhotoSize();
$result += \unpack('llocal_id', \stream_get_contents($fileId, 4));
} else {
$result += \unpack(LONG.'secret/llocal_id', \stream_get_contents($fileId, 12));
fixLong($result, 'volume_id');
fixLong($result, 'secret');
break;
case PHOTOSIZE_SOURCE_THUMBNAIL:
$result += \unpack('Vfile_type/athumbnail_type', \stream_get_contents($fileId, 8));
break;
case PHOTOSIZE_SOURCE_DIALOGPHOTO_BIG:
case PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL:
$result['photo_size'] = $result['photosize_source'] === PHOTOSIZE_SOURCE_DIALOGPHOTO_SMALL ? 'photo_small' : 'photo_big';
$result['dialog_id'] = unpackLong(\stream_get_contents($fileId, 8));
$result['dialog_access_hash'] = \unpack(LONG, \stream_get_contents($fileId, 8))[1];
fixLong($result, 'dialog_access_hash');
break;
case PHOTOSIZE_SOURCE_STICKERSET_THUMBNAIL:
$result += \unpack(LONG.'sticker_set_id/'.LONG.'sticker_set_access_hash', \stream_get_contents($fileId, 16));
fixLong($result, 'sticker_set_id');
fixLong($result, 'sticker_set_access_hash');
break;
}
}
$result += \unpack('llocal_id', \stream_get_contents($fileId, 4));
}
$l = \fstat($fileId)['size'] - \ftell($fileId);
$l -= $result['version'] >= 4 ? 2 : 1;
@ -560,15 +607,31 @@ function internalDecodeUnique(string $fileId): array
$l = \fstat($fileId)['size'] - \ftell($fileId);
} elseif (\strlen($fileId) === 12) {
// Legacy photos
$result += \unpack(LONG.'volume_id/llocal_id', $fileId);
fixLong($result, 'volume_id');
$l = 0;
} else {
} elseif (\strlen($fileId) === 9) {
// Dialog photos/thumbnails
$result += \unpack(LONG.'id/CsubType', $fileId);
fixLong($result, 'id');
$l = 0;
} elseif (\strlen($fileId) === 13) {
// Stickerset ID/version
$result += \unpack('CsubType/'.LONG.'sticker_set_id/lsticker_set_version', $fileId);
fixLong($result, 'sticker_set_id');
$l = 0;
} elseif (\strlen($fileId) === 8) {
// Any other document
$result += \unpack(LONG.'id', $fileId);
fixLong($result, 'id');
$l = \strlen($fileId) - 8;
$l = 0;
} else {
$l = strlen($fileId);
}
if ($l > 0) {
\trigger_error("Unique file ID $orig has $l bytes of leftover data");