Attempt to fix an out of memory crash.

This commit is contained in:
John Preston 2017-08-01 19:46:47 +03:00
parent 91f0d049db
commit 9d81ea59dd
2 changed files with 11 additions and 10 deletions

View file

@ -393,16 +393,16 @@ private:
int32 hashCrc32(const void *data, uint32 len); int32 hashCrc32(const void *data, uint32 len);
int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
inline std::array<char, 20> hashSha1(const void *data, int len) { inline std::array<char, 20> hashSha1(const void *data, int size) {
auto result = std::array<char, 20>(); auto result = std::array<char, 20>();
hashSha1(data, len, result.data()); hashSha1(data, size, result.data());
return result; return result;
} }
int32 *hashSha256(const void *data, uint32 len, void *dest); // dest - ptr to 32 bytes, returns (int32*)dest int32 *hashSha256(const void *data, uint32 len, void *dest); // dest - ptr to 32 bytes, returns (int32*)dest
inline std::array<char, 32> hashSha256(const void *data, int size) { inline std::array<char, 32> hashSha256(const void *data, int size) {
auto result = std::array<char, 32>(); auto result = std::array<char, 32>();
hashSha1(data, size, result.data()); hashSha256(data, size, result.data());
return result; return result;
} }

View file

@ -600,7 +600,7 @@ mtpFileLoader::CheckCdnHashResult mtpFileLoader::checkCdnFileHash(int offset, ba
return CheckCdnHashResult::NoHash; return CheckCdnHashResult::NoHash;
} }
auto realHash = hashSha256(bytes.data(), bytes.size()); auto realHash = hashSha256(bytes.data(), bytes.size());
if (!base::compare_bytes(gsl::as_bytes(gsl::make_span(realHash)), gsl::as_bytes(gsl::make_span(cdnFileHashIt->second.hash)))) { if (base::compare_bytes(gsl::as_bytes(gsl::make_span(realHash)), gsl::as_bytes(gsl::make_span(cdnFileHashIt->second.hash)))) {
return CheckCdnHashResult::Invalid; return CheckCdnHashResult::Invalid;
} }
return CheckCdnHashResult::Good; return CheckCdnHashResult::Good;
@ -620,9 +620,10 @@ void mtpFileLoader::getCdnFileHashesDone(const MTPVector<MTPCdnFileHash> &result
addCdnHashes(result.v); addCdnHashes(result.v);
auto someMoreChecked = false; auto someMoreChecked = false;
for (auto i = _cdnUncheckedParts.begin(); i != _cdnUncheckedParts.cend();) { for (auto i = _cdnUncheckedParts.begin(); i != _cdnUncheckedParts.cend();) {
auto bytes = gsl::as_bytes(gsl::make_span(i->second)); auto uncheckedOffset = i->first;
auto uncheckedBytes = gsl::as_bytes(gsl::make_span(i->second));
switch (checkCdnFileHash(offset, bytes)) { switch (checkCdnFileHash(uncheckedOffset, uncheckedBytes)) {
case CheckCdnHashResult::NoHash: { case CheckCdnHashResult::NoHash: {
++i; ++i;
} break; } break;
@ -635,12 +636,12 @@ void mtpFileLoader::getCdnFileHashesDone(const MTPVector<MTPCdnFileHash> &result
case CheckCdnHashResult::Good: { case CheckCdnHashResult::Good: {
someMoreChecked = true; someMoreChecked = true;
auto goodOffset = i->first; auto goodOffset = uncheckedOffset;
auto goodBytes = std::move(i->second); auto goodBytes = std::move(i->second);
i = _cdnUncheckedParts.erase(i); i = _cdnUncheckedParts.erase(i);
auto finished = (i == _cdnUncheckedParts.cend()); auto guarded = QPointer<mtpFileLoader>(this);
partLoaded(goodOffset, gsl::as_bytes(gsl::make_span(goodBytes))); partLoaded(goodOffset, gsl::as_bytes(gsl::make_span(goodBytes)));
if (finished) { if (!guarded) {
// Perhaps we were destroyed already?.. // Perhaps we were destroyed already?..
return; return;
} }
@ -721,7 +722,7 @@ void mtpFileLoader::partLoaded(int offset, base::const_byte_span bytes) {
if (!bytes.size() || (bytes.size() % 1024)) { // bad next offset if (!bytes.size() || (bytes.size() % 1024)) { // bad next offset
_lastComplete = true; _lastComplete = true;
} }
if (_sentRequests.empty() && (_lastComplete || (_size && _nextRequestOffset >= _size))) { if (_sentRequests.empty() && _cdnUncheckedParts.empty() && (_lastComplete || (_size && _nextRequestOffset >= _size))) {
if (!_fname.isEmpty() && (_toCache == LoadToCacheAsWell)) { if (!_fname.isEmpty() && (_toCache == LoadToCacheAsWell)) {
if (!_fileIsOpen) _fileIsOpen = _file.open(QIODevice::WriteOnly); if (!_fileIsOpen) _fileIsOpen = _file.open(QIODevice::WriteOnly);
if (!_fileIsOpen) { if (!_fileIsOpen) {