From abbc474480192c7f37c2c50941c7ae0be19d0177 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 6 Sep 2022 11:52:19 +0200 Subject: [PATCH] fix: Check ahead of download if a file exceeds the maximum file size fixes https://gitlab.com/famedly/company/frontend/famedly-web/-/issues/539 --- lib/src/client.dart | 36 ++++++++++++++++++++++++++++++++++++ lib/src/room.dart | 6 ++++++ 2 files changed, 42 insertions(+) diff --git a/lib/src/client.dart b/lib/src/client.dart index 0ada71b7..4890e5bb 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -19,6 +19,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:core'; +import 'dart:math'; import 'dart:typed_data'; import 'package:collection/collection.dart' show IterableExtension; @@ -887,6 +888,12 @@ class Client extends MatrixApi { @override Future uploadContent(Uint8List file, {String? filename, String? contentType}) async { + final mediaConfig = await getConfig(); + final maxMediaSize = mediaConfig.mUploadSize; + if (maxMediaSize != null && maxMediaSize < file.lengthInBytes) { + throw FileTooBigMatrixException(file.lengthInBytes, maxMediaSize); + } + contentType ??= lookupMimeType(filename ?? '', headerBytes: file); final mxc = await super .uploadContent(file, filename: filename, contentType: contentType); @@ -2904,6 +2911,35 @@ class BadServerLoginTypesException implements Exception { 'Server supports the Login Types: ${serverLoginTypes.toString()} but this application is only compatible with ${supportedLoginTypes.toString()}.'; } +class FileTooBigMatrixException extends MatrixException { + int actualFileSize; + int maxFileSize; + + static String _formatFileSize(int size) { + if (size < 1024) return '$size B'; + final i = (log(size) / log(1024)).floor(); + final num = (size / pow(1024, i)); + final round = num.round(); + final numString = round < 10 + ? num.toStringAsFixed(2) + : round < 100 + ? num.toStringAsFixed(1) + : round.toString(); + return '$numString ${'kMGTPEZY'[i - 1]}B'; + } + + FileTooBigMatrixException(this.actualFileSize, this.maxFileSize) + : super.fromJson({ + 'errcode': MatrixError.M_TOO_LARGE, + 'error': + 'File size ${_formatFileSize(actualFileSize)} exceeds allowed maximum of ${_formatFileSize(maxFileSize)}' + }); + + @override + String toString() => + 'File size ${_formatFileSize(actualFileSize)} exceeds allowed maximum of ${_formatFileSize(maxFileSize)}'; +} + class HomeserverSummary { final DiscoveryInformation? discoveryInformation; final GetVersionsResponse versions; diff --git a/lib/src/room.dart b/lib/src/room.dart index d4c80d26..c5480132 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -672,6 +672,12 @@ class Room { MatrixImageFile? thumbnail, Map? extraContent, }) async { + final mediaConfig = await client.getConfig(); + final maxMediaSize = mediaConfig.mUploadSize; + if (maxMediaSize != null && maxMediaSize < file.bytes.lengthInBytes) { + throw FileTooBigMatrixException(file.bytes.lengthInBytes, maxMediaSize); + } + txid ??= client.generateUniqueTransactionId(); sendingFilePlaceholders[txid] = file; if (thumbnail != null) {