diff --git a/Telegram/SourceFiles/core/file_utilities.cpp b/Telegram/SourceFiles/core/file_utilities.cpp
index 6be11623d..14c87c0d5 100644
--- a/Telegram/SourceFiles/core/file_utilities.cpp
+++ b/Telegram/SourceFiles/core/file_utilities.cpp
@@ -154,6 +154,53 @@ QString DefaultDownloadPath() {
 		+ '/';
 }
 
+QString NameFromUserString(QString name) {
+	static const auto Bad = { '/', '\\', '<', '>', ':', '"', '|', '?', '*' };
+	for (auto &ch : name) {
+		if (ch < 32 || ranges::find(Bad, ch.unicode()) != end(Bad)) {
+			ch = '_';
+		}
+	}
+	if (name.isEmpty() || name.endsWith(' ') || name.endsWith('.')) {
+		name.append('_');
+	}
+#ifdef Q_OS_WIN
+	static const auto BadNames = {
+		qstr("CON"),
+		qstr("PRN"),
+		qstr("AUX"),
+		qstr("NUL"),
+		qstr("COM1"),
+		qstr("COM2"),
+		qstr("COM3"),
+		qstr("COM4"),
+		qstr("COM5"),
+		qstr("COM6"),
+		qstr("COM7"),
+		qstr("COM8"),
+		qstr("COM9"),
+		qstr("LPT1"),
+		qstr("LPT2"),
+		qstr("LPT3"),
+		qstr("LPT4"),
+		qstr("LPT5"),
+		qstr("LPT6"),
+		qstr("LPT7"),
+		qstr("LPT8"),
+		qstr("LPT9")
+	};
+	for (const auto bad : BadNames) {
+		if (name.startsWith(bad, Qt::CaseInsensitive)) {
+			if (name.size() == bad.size() || name[bad.size()] == '.') {
+				name = '_' + name;
+				break;
+			}
+		}
+	}
+#endif // Q_OS_WIN
+	return name;
+}
+
 namespace internal {
 
 void UnsafeOpenEmailLinkDefault(const QString &email) {
diff --git a/Telegram/SourceFiles/core/file_utilities.h b/Telegram/SourceFiles/core/file_utilities.h
index b99852b20..8d913f2a9 100644
--- a/Telegram/SourceFiles/core/file_utilities.h
+++ b/Telegram/SourceFiles/core/file_utilities.h
@@ -35,7 +35,9 @@ void OpenWith(const QString &filepath, QPoint menuPosition);
 void Launch(const QString &filepath);
 void ShowInFolder(const QString &filepath);
 
-QString DefaultDownloadPath();
+[[nodiscard]] QString DefaultDownloadPath();
+
+[[nodiscard]] QString NameFromUserString(QString name);
 
 namespace internal {
 
diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
index c73a610f3..7016b59a0 100644
--- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
@@ -369,7 +369,7 @@ SendMediaReady PrepareThemeMedia(
 	//};
 	//push("s", scaled(320));
 
-	const auto filename = QString(name).replace(' ', '_')
+	const auto filename = File::NameFromUserString(name)
 		+ qsl(".tdesktop-theme"); // #TODO themes
 	auto attributes = QVector<MTPDocumentAttribute>(
 		1,