Move DumpToText from Telegram to lib_mtproto.

This commit is contained in:
John Preston 2019-11-14 18:29:45 +03:00
parent 7243fb52ad
commit 8b14249cd2
11 changed files with 262 additions and 228 deletions

View File

@ -28,7 +28,6 @@ generate({
'buffer': 'mtpBuffer',
},
'sections': [
'serialization',
'read-write',
],
@ -91,4 +90,8 @@ generate({
},
'builtinInclude': 'mtproto/core_types.h',
'dumpToText': {
'include': 'mtproto/details/mtproto_dump_to_text.h',
},
})

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/details/mtproto_dc_key_creator.h"
#include "mtproto/details/mtproto_dc_key_checker.h"
#include "mtproto/details/mtproto_dump_to_text.h"
#include "mtproto/session.h"
#include "mtproto/rsa_public_key.h"
#include "mtproto/rpc_sender.h"
@ -1433,7 +1434,7 @@ void ConnectionPrivate::handleReceived() {
auto from = decryptedInts + kEncryptedHeaderIntsCount;
auto end = from + (messageLength / kIntSize);
auto sfrom = decryptedInts + 4U; // msg_id + seq_no + length + message
MTP_LOG(_shiftedDcId, ("Recv: ") + mtpTextSerialize(sfrom, end));
MTP_LOG(_shiftedDcId, ("Recv: ") + details::DumpToText(sfrom, end));
bool needToHandle = false;
{
@ -2622,7 +2623,7 @@ bool ConnectionPrivate::sendSecureRequest(
memcpy(request->data() + 2, &session, 2 * sizeof(mtpPrime));
auto from = request->constData() + 4;
MTP_LOG(_shiftedDcId, ("Send: ") + mtpTextSerialize(from, from + messageSize));
MTP_LOG(_shiftedDcId, ("Send: ") + details::DumpToText(from, from + messageSize));
#ifdef TDESKTOP_MTPROTO_OLD
uint32 padding = fullSize - 4 - messageSize;

View File

@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "mtproto/core_types.h"
#include "zlib.h"
namespace MTP {
namespace {
@ -175,149 +173,3 @@ const void *SecureRequest::dataInBytes() const {
}
} // namespace MTP
bool mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
switch (mtpTypeId(cons)) {
case mtpc_int: {
MTPint value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [INT]");
return true;
}
} break;
case mtpc_long: {
MTPlong value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [LONG]");
return true;
}
} break;
case mtpc_int128: {
MTPint128 value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.h)).add(" * 2^64 + ").add(QString::number(value.l)).add(" [INT128]");
return true;
}
} break;
case mtpc_int256: {
MTPint256 value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.h.h)).add(" * 2^192 + ").add(QString::number(value.h.l)).add(" * 2^128 + ").add(QString::number(value.l.h)).add(" * 2 ^ 64 + ").add(QString::number(value.l.l)).add(" [INT256]");
return true;
}
} break;
case mtpc_double: {
MTPdouble value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [DOUBLE]");
return true;
}
} break;
case mtpc_string: {
MTPstring value;
if (value.read(from, end, cons)) {
auto strUtf8 = value.v;
auto str = QString::fromUtf8(strUtf8);
if (str.toUtf8() == strUtf8) {
to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
} else if (strUtf8.size() < 64) {
to.add(Logs::mb(strUtf8.constData(), strUtf8.size()).str()).add(" [").add(QString::number(strUtf8.size())).add(" BYTES]");
} else {
to.add(Logs::mb(strUtf8.constData(), 16).str()).add("... [").add(QString::number(strUtf8.size())).add(" BYTES]");
}
return true;
}
} break;
case mtpc_vector: {
if (from < end) {
int32 cnt = *(from++);
to.add("[ vector<0x").add(QString::number(vcons, 16)).add(">");
if (cnt) {
to.add("\n").addSpaces(level);
for (int32 i = 0; i < cnt; ++i) {
to.add(" ");
if (!mtpTextSerializeType(to, from, end, vcons, level + 1)) {
return false;
}
to.add(",\n").addSpaces(level);
}
} else {
to.add(" ");
}
to.add("]");
return true;
}
} break;
case mtpc_gzip_packed: {
MTPstring packed;
// read packed string as serialized mtp string type
if (!packed.read(from, end)) {
return false;
}
uint32 packedLen = packed.v.size(), unpackedChunk = packedLen;
mtpBuffer result; // * 4 because of mtpPrime type
result.resize(0);
z_stream stream;
stream.zalloc = nullptr;
stream.zfree = nullptr;
stream.opaque = nullptr;
stream.avail_in = 0;
stream.next_in = nullptr;
int res = inflateInit2(&stream, 16 + MAX_WBITS);
if (res != Z_OK) {
return false;
}
stream.avail_in = packedLen;
stream.next_in = reinterpret_cast<Bytef*>(packed.v.data());
stream.avail_out = 0;
while (!stream.avail_out) {
result.resize(result.size() + unpackedChunk);
stream.avail_out = unpackedChunk * sizeof(mtpPrime);
stream.next_out = (Bytef*)&result[result.size() - unpackedChunk];
int res = inflate(&stream, Z_NO_FLUSH);
if (res != Z_OK && res != Z_STREAM_END) {
inflateEnd(&stream);
return false;
}
}
if (stream.avail_out & 0x03) {
return false;
}
result.resize(result.size() - (stream.avail_out >> 2));
inflateEnd(&stream);
if (result.empty()) {
return false;
}
const mtpPrime *newFrom = result.constData(), *newEnd = result.constData() + result.size();
to.add("[GZIPPED] ");
return mtpTextSerializeType(to, newFrom, newEnd, 0, level);
} break;
default: {
for (uint32 i = 1; i < mtpLayerMaxSingle; ++i) {
if (cons == mtpLayers[i]) {
to.add("[LAYER").add(QString::number(i + 1)).add("] ");
return mtpTextSerializeType(to, from, end, 0, level);
}
}
if (cons == mtpc_invokeWithLayer) {
if (from >= end) {
return false;
}
int32 layer = *(from++);
to.add("[LAYER").add(QString::number(layer)).add("] ");
return mtpTextSerializeType(to, from, end, 0, level);
}
} break;
}
return false;
}

View File

@ -335,80 +335,6 @@ inline MTPvector<T> MTP_vector() {
return tl::make_vector<T>();
}
// Human-readable text serialization
struct MTPStringLogger {
static constexpr auto kBufferSize = 1024 * 1024; // 1 mb start size
MTPStringLogger()
: p(new char[kBufferSize])
, alloced(kBufferSize) {
}
~MTPStringLogger() {
delete[] p;
}
MTPStringLogger &add(const QString &data) {
auto d = data.toUtf8();
return add(d.constData(), d.size());
}
MTPStringLogger &add(const char *data, int32 len = -1) {
if (len < 0) len = strlen(data);
if (!len) return (*this);
ensureLength(len);
memcpy(p + size, data, len);
size += len;
return (*this);
}
MTPStringLogger &addSpaces(int32 level) {
int32 len = level * 2;
if (!len) return (*this);
ensureLength(len);
for (char *ptr = p + size, *end = ptr + len; ptr != end; ++ptr) {
*ptr = ' ';
}
size += len;
return (*this);
}
MTPStringLogger &error(const char *problem = "could not decode type") {
return add("[ERROR] (").add(problem).add(")");
}
void ensureLength(int32 add) {
if (size + add <= alloced) return;
int32 newsize = size + add;
if (newsize % kBufferSize) {
newsize += kBufferSize - (newsize % kBufferSize);
}
char *b = new char[newsize];
memcpy(b, p, size);
alloced = newsize;
delete[] p;
p = b;
}
char *p = nullptr;
int size = 0;
int alloced = 0;
};
[[nodiscard]] bool mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons = 0, uint32 level = 0, mtpPrime vcons = 0);
[[nodiscard]] bool mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons = 0);
inline QString mtpTextSerialize(const mtpPrime *&from, const mtpPrime *end) {
MTPStringLogger to;
[[maybe_unused]] bool result = mtpTextSerializeType(to, from, end, mtpc_core_message);
return QString::fromUtf8(to.p, to.size);
}
namespace tl {
template <typename Accumulator>

View File

@ -0,0 +1,168 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "mtproto/details/mtproto_dump_to_text.h"
#include "base/zlib_help.h"
#include "scheme-dump_to_text.h"
#include "scheme.h"
namespace MTP::details {
bool DumpToTextCore(DumpToTextBuffer &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
switch (mtpTypeId(cons)) {
case mtpc_int: {
MTPint value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [INT]");
return true;
}
} break;
case mtpc_long: {
MTPlong value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [LONG]");
return true;
}
} break;
case mtpc_int128: {
MTPint128 value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.h)).add(" * 2^64 + ").add(QString::number(value.l)).add(" [INT128]");
return true;
}
} break;
case mtpc_int256: {
MTPint256 value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.h.h)).add(" * 2^192 + ").add(QString::number(value.h.l)).add(" * 2^128 + ").add(QString::number(value.l.h)).add(" * 2 ^ 64 + ").add(QString::number(value.l.l)).add(" [INT256]");
return true;
}
} break;
case mtpc_double: {
MTPdouble value;
if (value.read(from, end, cons)) {
to.add(QString::number(value.v)).add(" [DOUBLE]");
return true;
}
} break;
case mtpc_string: {
MTPstring value;
if (value.read(from, end, cons)) {
auto strUtf8 = value.v;
auto str = QString::fromUtf8(strUtf8);
if (str.toUtf8() == strUtf8) {
to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
} else if (strUtf8.size() < 64) {
to.add(Logs::mb(strUtf8.constData(), strUtf8.size()).str()).add(" [").add(QString::number(strUtf8.size())).add(" BYTES]");
} else {
to.add(Logs::mb(strUtf8.constData(), 16).str()).add("... [").add(QString::number(strUtf8.size())).add(" BYTES]");
}
return true;
}
} break;
case mtpc_vector: {
if (from < end) {
int32 cnt = *(from++);
to.add("[ vector<0x").add(QString::number(vcons, 16)).add(">");
if (cnt) {
to.add("\n").addSpaces(level);
for (int32 i = 0; i < cnt; ++i) {
to.add(" ");
if (!DumpToTextType(to, from, end, vcons, level + 1)) {
return false;
}
to.add(",\n").addSpaces(level);
}
} else {
to.add(" ");
}
to.add("]");
return true;
}
} break;
case mtpc_gzip_packed: {
MTPstring packed;
// read packed string as serialized mtp string type
if (!packed.read(from, end)) {
return false;
}
uint32 packedLen = packed.v.size(), unpackedChunk = packedLen;
mtpBuffer result; // * 4 because of mtpPrime type
result.resize(0);
z_stream stream;
stream.zalloc = nullptr;
stream.zfree = nullptr;
stream.opaque = nullptr;
stream.avail_in = 0;
stream.next_in = nullptr;
int res = inflateInit2(&stream, 16 + MAX_WBITS);
if (res != Z_OK) {
return false;
}
stream.avail_in = packedLen;
stream.next_in = reinterpret_cast<Bytef*>(packed.v.data());
stream.avail_out = 0;
while (!stream.avail_out) {
result.resize(result.size() + unpackedChunk);
stream.avail_out = unpackedChunk * sizeof(mtpPrime);
stream.next_out = (Bytef*)&result[result.size() - unpackedChunk];
int res = inflate(&stream, Z_NO_FLUSH);
if (res != Z_OK && res != Z_STREAM_END) {
inflateEnd(&stream);
return false;
}
}
if (stream.avail_out & 0x03) {
return false;
}
result.resize(result.size() - (stream.avail_out >> 2));
inflateEnd(&stream);
if (result.empty()) {
return false;
}
const mtpPrime *newFrom = result.constData(), *newEnd = result.constData() + result.size();
to.add("[GZIPPED] ");
return DumpToTextType(to, newFrom, newEnd, 0, level);
} break;
default: {
for (uint32 i = 1; i < mtpLayerMaxSingle; ++i) {
if (cons == mtpLayers[i]) {
to.add("[LAYER").add(QString::number(i + 1)).add("] ");
return DumpToTextType(to, from, end, 0, level);
}
}
if (cons == mtpc_invokeWithLayer) {
if (from >= end) {
return false;
}
int32 layer = *(from++);
to.add("[LAYER").add(QString::number(layer)).add("] ");
return DumpToTextType(to, from, end, 0, level);
}
} break;
}
return false;
}
QString DumpToText(const mtpPrime *&from, const mtpPrime *end) {
DumpToTextBuffer to;
[[maybe_unused]] bool result = DumpToTextType(to, from, end, mtpc_core_message);
return QString::fromUtf8(to.p, to.size);
}
} // namespace MTP::details

View File

@ -0,0 +1,81 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/core_types.h"
namespace MTP::details {
// Human-readable text serialization
QString DumpToText(const mtpPrime *&from, const mtpPrime *end);
struct DumpToTextBuffer {
static constexpr auto kBufferSize = 1024 * 1024; // 1 mb start size
DumpToTextBuffer()
: p(new char[kBufferSize])
, alloced(kBufferSize) {
}
~DumpToTextBuffer() {
delete[] p;
}
DumpToTextBuffer &add(const QString &data) {
auto d = data.toUtf8();
return add(d.constData(), d.size());
}
DumpToTextBuffer &add(const char *data, int32 len = -1) {
if (len < 0) len = strlen(data);
if (!len) return (*this);
ensureLength(len);
memcpy(p + size, data, len);
size += len;
return (*this);
}
DumpToTextBuffer &addSpaces(int32 level) {
int32 len = level * 2;
if (!len) return (*this);
ensureLength(len);
for (char *ptr = p + size, *end = ptr + len; ptr != end; ++ptr) {
*ptr = ' ';
}
size += len;
return (*this);
}
DumpToTextBuffer &error(const char *problem = "could not decode type") {
return add("[ERROR] (").add(problem).add(")");
}
void ensureLength(int32 add) {
if (size + add <= alloced) return;
int32 newsize = size + add;
if (newsize % kBufferSize) {
newsize += kBufferSize - (newsize % kBufferSize);
}
char *b = new char[newsize];
memcpy(b, p, size);
alloced = newsize;
delete[] p;
p = b;
}
char *p = nullptr;
int size = 0;
int alloced = 0;
};
[[nodiscard]] bool DumpToTextCore(DumpToTextBuffer &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons = 0);
} // namespace MTP::details

View File

@ -99,7 +99,6 @@
'<(SHARED_INTERMEDIATE_DIR)',
'<(libs_loc)/breakpad/src',
'<(libs_loc)/lzma/C',
'<(libs_loc)/zlib',
'<(libs_loc)/openal-soft/include',
'<(libs_loc)/opus/include',
'<(minizip_loc)',

View File

@ -38,6 +38,8 @@
'<(src_loc)/mtproto/details/mtproto_dc_key_checker.h',
'<(src_loc)/mtproto/details/mtproto_dc_key_creator.cpp',
'<(src_loc)/mtproto/details/mtproto_dc_key_creator.h',
'<(src_loc)/mtproto/details/mtproto_dump_to_text.cpp',
'<(src_loc)/mtproto/details/mtproto_dump_to_text.h',
'<(src_loc)/mtproto/mtproto_dh_utils.cpp',
'<(src_loc)/mtproto/mtproto_dh_utils.h',
'<(src_loc)/mtproto/mtproto_proxy_data.cpp',

View File

@ -50,6 +50,8 @@
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/scheme.cpp',
'<(SHARED_INTERMEDIATE_DIR)/scheme.h',
'<(SHARED_INTERMEDIATE_DIR)/scheme-dump_to_text.cpp',
'<(SHARED_INTERMEDIATE_DIR)/scheme-dump_to_text.h',
],
'action': [
'python', '<(src_loc)/codegen/scheme/codegen_scheme.py',

@ -1 +1 @@
Subproject commit c1941996febf02c4216a16fc6037e7473bcf9d00
Subproject commit bdc4127ff5d5a14eb9d04986725ef7ec94e6d807

@ -1 +1 @@
Subproject commit 89a1e3fed24bc0bfc268fa0352e7d2658ee4ef22
Subproject commit 2bf101114f0a54c868a2703a9a80c06c0f2d2c41