From f20d9395d1c834c9735670d78bd467c5b9c5647c Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Wed, 26 Jun 2019 10:55:08 +0200
Subject: [PATCH] Unpack lottie gzip to std::string for rlottie.

---
 .../SourceFiles/lottie/lottie_animation.cpp   | 31 +++++++++----------
 Telegram/SourceFiles/lottie/lottie_common.h   |  7 -----
 .../lottie/lottie_frame_renderer.cpp          |  2 +-
 .../lottie/lottie_frame_renderer.h            |  2 +-
 4 files changed, 16 insertions(+), 26 deletions(-)

diff --git a/Telegram/SourceFiles/lottie/lottie_animation.cpp b/Telegram/SourceFiles/lottie/lottie_animation.cpp
index ed59dacbe..64f620d7e 100644
--- a/Telegram/SourceFiles/lottie/lottie_animation.cpp
+++ b/Telegram/SourceFiles/lottie/lottie_animation.cpp
@@ -21,7 +21,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 namespace Lottie {
 namespace {
 
-QByteArray UnpackGzip(const QByteArray &bytes) {
+std::string UnpackGzip(const QByteArray &bytes) {
+	const auto original = [&] {
+		return std::string(bytes.constData(), bytes.size());
+	};
 	z_stream stream;
 	stream.zalloc = nullptr;
 	stream.zfree = nullptr;
@@ -30,11 +33,11 @@ QByteArray UnpackGzip(const QByteArray &bytes) {
 	stream.next_in = nullptr;
 	int res = inflateInit2(&stream, 16 + MAX_WBITS);
 	if (res != Z_OK) {
-		return bytes;
+		return original();
 	}
 	const auto guard = gsl::finally([&] { inflateEnd(&stream); });
 
-	auto result = QByteArray(kMaxFileSize + 1, Qt::Uninitialized);
+	auto result = std::string(kMaxFileSize + 1, char(0));
 	stream.avail_in = bytes.size();
 	stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(bytes.data()));
 	stream.avail_out = 0;
@@ -43,9 +46,9 @@ QByteArray UnpackGzip(const QByteArray &bytes) {
 		stream.next_out = reinterpret_cast<Bytef*>(result.data());
 		int res = inflate(&stream, Z_NO_FLUSH);
 		if (res != Z_OK && res != Z_STREAM_END) {
-			return bytes;
+			return original();
 		} else if (!stream.avail_out) {
-			return bytes;
+			return original();
 		}
 	}
 	result.resize(result.size() - stream.avail_out);
@@ -75,21 +78,16 @@ auto Init(QByteArray &&content)
 			<< content.size();
 		return Error::ParseFailed;
 	}
-	content = UnpackGzip(content);
-	if (content.size() > kMaxFileSize) {
-		qWarning()
-			<< "Lottie Error: Too large file: "
-			<< content.size();
-		return Error::ParseFailed;
-	}
-	auto animation = rlottie::Animation::loadFromData(
-		std::string(content.constData(), content.size()),
-		std::string());
+	const auto string = UnpackGzip(content);
+	Assert(string.size() <= kMaxFileSize);
+
+	auto animation = rlottie::Animation::loadFromData(string, std::string());
 	if (!animation) {
 		qWarning()
 			<< "Lottie Error: Parse failed.";
 		return Error::ParseFailed;
 	}
+
 	auto result = std::make_unique<SharedState>(std::move(animation));
 	auto information = result->information();
 	if (!information.frameRate
@@ -154,8 +152,7 @@ QImage Animation::frame(const FrameRequest &request) const {
 	Expects(_renderer != nullptr);
 
 	const auto frame = _state->frameForPaint();
-	const auto changed = (frame->request != request)
-		&& (request.strict || !frame->request.strict);
+	const auto changed = (frame->request != request);
 	if (changed) {
 		frame->request = request;
 		_renderer->updateFrameRequest(_state, request);
diff --git a/Telegram/SourceFiles/lottie/lottie_common.h b/Telegram/SourceFiles/lottie/lottie_common.h
index 5e593af47..21dbb1898 100644
--- a/Telegram/SourceFiles/lottie/lottie_common.h
+++ b/Telegram/SourceFiles/lottie/lottie_common.h
@@ -49,13 +49,6 @@ enum class Error {
 struct FrameRequest {
 	QSize resize;
 	std::optional<QColor> colored;
-	bool strict = true;
-
-	static FrameRequest NonStrict() {
-		auto result = FrameRequest();
-		result.strict = false;
-		return result;
-	}
 
 	bool empty() const {
 		return resize.isEmpty();
diff --git a/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp b/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp
index 41f18d35c..ce0c03195 100644
--- a/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp
+++ b/Telegram/SourceFiles/lottie/lottie_frame_renderer.cpp
@@ -180,7 +180,7 @@ SharedState::SharedState(std::unique_ptr<rlottie::Animation> animation)
 	calculateProperties();
 	if (isValid()) {
 		auto cover = QImage();
-		renderFrame(cover, FrameRequest::NonStrict(), 0);
+		renderFrame(cover, FrameRequest(), 0);
 		init(std::move(cover));
 	}
 }
diff --git a/Telegram/SourceFiles/lottie/lottie_frame_renderer.h b/Telegram/SourceFiles/lottie/lottie_frame_renderer.h
index 9c1353550..883e6bdc7 100644
--- a/Telegram/SourceFiles/lottie/lottie_frame_renderer.h
+++ b/Telegram/SourceFiles/lottie/lottie_frame_renderer.h
@@ -32,7 +32,7 @@ struct Frame {
 	crl::time displayed = kTimeUnknown;
 	crl::time display = kTimeUnknown;
 
-	FrameRequest request = FrameRequest::NonStrict();
+	FrameRequest request;
 	QImage prepared;
 };