diff options
-rw-r--r-- | cli/onionshare_cli/resources/templates/receive.html | 2 | ||||
-rw-r--r-- | cli/onionshare_cli/web/chat_mode.py | 31 | ||||
-rw-r--r-- | cli/onionshare_cli/web/receive_mode.py | 7 | ||||
-rw-r--r-- | desktop/onionshare/tab/mode/history.py | 5 |
4 files changed, 39 insertions, 6 deletions
diff --git a/cli/onionshare_cli/resources/templates/receive.html b/cli/onionshare_cli/resources/templates/receive.html index 159bfac5..90f10798 100644 --- a/cli/onionshare_cli/resources/templates/receive.html +++ b/cli/onionshare_cli/resources/templates/receive.html @@ -53,7 +53,7 @@ <p><input type="file" id="file-select" name="file[]" multiple /></p> {% endif %} {% if not disable_text %} - <p><textarea id="text" name="text" placeholder="Write a message"></textarea></p> + <p><textarea id="text" name="text" placeholder="Write a message (max length 524288 characters)" maxlength="524288"></textarea></p> {% endif %} <p><button type="submit" id="send-button" class="button">Submit</button></p> </form> diff --git a/cli/onionshare_cli/web/chat_mode.py b/cli/onionshare_cli/web/chat_mode.py index 514258b9..85eb94ff 100644 --- a/cli/onionshare_cli/web/chat_mode.py +++ b/cli/onionshare_cli/web/chat_mode.py @@ -17,6 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ +import unicodedata from flask import request, render_template, make_response, jsonify, session from flask_socketio import emit, ConnectionRefusedError @@ -47,12 +48,38 @@ class ChatModeWeb: self.define_routes() + def remove_unallowed_characters(self, text): + """ + Sanitize username to remove unwanted characters. + Allowed characters right now are: + - all ASCII numbers + - all ASCII letters + - dash, underscore and single space + """ + + def allowed_character(ch): + allowed_unicode_categories = [ + 'L', # All letters + 'N', # All numbers + ] + allowed_special_characters = [ + '-', # dash + '_', # underscore + ' ', # single space + ] + return ( + unicodedata.category(ch)[0] in allowed_unicode_categories and ord(ch) < 128 + ) or ch in allowed_special_characters + + return "".join( + ch for ch in text if allowed_character(ch) + ) + def validate_username(self, username): try: - username = username.strip() + username = self.remove_unallowed_characters(username.strip()) return ( username - and username.isascii() and username not in self.connected_users and len(username) < 128 ) diff --git a/cli/onionshare_cli/web/receive_mode.py b/cli/onionshare_cli/web/receive_mode.py index 9ddf22ff..a25f82a1 100644 --- a/cli/onionshare_cli/web/receive_mode.py +++ b/cli/onionshare_cli/web/receive_mode.py @@ -194,7 +194,10 @@ class ReceiveModeWeb: if files_received > 0: msg = f"Uploaded {files_msg}" else: - msg = "Nothing submitted" + if not self.web.settings.get("receive", "disable_text"): + msg = "Nothing submitted or message was too long (> 524288 characters)" + else: + msg = "Nothing submitted" if ajax: info_flashes.append(msg) @@ -462,7 +465,7 @@ class ReceiveModeRequest(Request): self.includes_message = False if not self.web.settings.get("receive", "disable_text"): text_message = self.form.get("text") - if text_message: + if text_message and len(text_message) <= 524288: if text_message.strip() != "": self.includes_message = True diff --git a/desktop/onionshare/tab/mode/history.py b/desktop/onionshare/tab/mode/history.py index 3afdfc15..ad8af099 100644 --- a/desktop/onionshare/tab/mode/history.py +++ b/desktop/onionshare/tab/mode/history.py @@ -23,6 +23,7 @@ import subprocess import os from datetime import datetime from PySide6 import QtCore, QtWidgets, QtGui +from urllib.parse import unquote from ... import strings from ...widgets import Alert @@ -464,7 +465,9 @@ class IndividualFileHistoryItem(HistoryItem): self.common = common self.id = id - self.path = path + # Decode and sanitize the path to remove newlines + decoded_path = unquote(path) + self.path = decoded_path.replace("\r", "").replace("\n", "") self.total_bytes = 0 self.downloaded_bytes = 0 self.started = time.time() |