diff --git a/include/mtx/events_impl.hpp b/include/mtx/events_impl.hpp index 4d204989c5029c10a6aae5d496d75f74db4bad87..e8e3a6fe10fe51c18ddfff3f1ed81384886830e0 100644 --- a/include/mtx/events_impl.hpp +++ b/include/mtx/events_impl.hpp @@ -54,9 +54,18 @@ from_json(const nlohmann::json &obj, Event<Content> &event) event.content = {}; } - event.type = getEventType(obj.at("type").get<std::string>()); + auto type = obj.at("type").get<std::string>(); + if (type.size() > 255) { + throw std::out_of_range("Type exceeds 255 bytes"); + } + event.type = getEventType(type); + event.sender = obj.value("sender", ""); + if (event.sender.size() > 255) { + throw std::out_of_range("Sender exceeds 255 bytes"); + } + if constexpr (std::is_same_v<Unknown, Content>) event.content.type = obj.at("type").get<std::string>(); } @@ -135,6 +144,10 @@ from_json(const nlohmann::json &obj, StrippedEvent<Content> &event) from_json(obj, base); event.state_key = obj.at("state_key").get<std::string>(); + + if (event.state_key.size() > 255) { + throw std::out_of_range("State key exceeds 255 bytes"); + } } template<class Content> @@ -154,13 +167,22 @@ from_json(const nlohmann::json &obj, RoomEvent<Content> &event) Event<Content> &base = event; from_json(obj, base); - event.event_id = obj.at("event_id").get<std::string>(); + event.event_id = obj.at("event_id").get<std::string>(); + + if (event.event_id.size() > 255) { + throw std::out_of_range("Event id exceeds 255 bytes"); + } + event.origin_server_ts = obj.at("origin_server_ts").get<uint64_t>(); // SPEC_BUG: Not present in the state array returned by /sync. if (obj.find("room_id") != obj.end()) event.room_id = obj.at("room_id").get<std::string>(); + if (event.room_id.size() > 255) { + throw std::out_of_range("Room id exceeds 255 bytes"); + } + if (obj.find("unsigned") != obj.end()) event.unsigned_data = obj.at("unsigned").get<UnsignedData>(); } @@ -198,6 +220,10 @@ from_json(const nlohmann::json &obj, StateEvent<Content> &event) from_json(obj, base); event.state_key = obj.at("state_key").get<std::string>(); + + if (event.state_key.size() > 255) { + throw std::out_of_range("State key exceeds 255 bytes"); + } } template<class Content> @@ -261,6 +287,10 @@ from_json(const nlohmann::json &obj, EphemeralEvent<Content> &event) if (obj.contains("room_id")) event.room_id = obj.at("room_id").get<std::string>(); + + if (event.room_id.size() > 255) { + throw std::out_of_range("Room id exceeds 255 bytes"); + } } } diff --git a/lib/structs/responses/common.cpp b/lib/structs/responses/common.cpp index bee5228cafd87d0b4473bcc925a9d90dad68eb73..79a0f4fa26f1ed50869cf4d7316310fdc65c0fbe 100644 --- a/lib/structs/responses/common.cpp +++ b/lib/structs/responses/common.cpp @@ -198,7 +198,7 @@ parse_room_account_data_events( case events::EventType::ImagePackInRoom: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { log_error(err, e); } } @@ -506,7 +506,7 @@ parse_timeline_events(const json &events, case events::EventType::Dummy: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { log_error(err, e); } } @@ -604,7 +604,7 @@ parse_device_events(const json &events, default: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { log_error(err, e); } } @@ -779,7 +779,7 @@ parse_state_events(const json &events, case events::EventType::Dummy: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { log_error(err, e); } } @@ -942,7 +942,7 @@ parse_stripped_events(const json &events, case events::EventType::Dummy: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { log_error(err, e); } } @@ -976,7 +976,7 @@ parse_ephemeral_events(const json &events, default: continue; } - } catch (json::exception &err) { + } catch (std::exception &err) { utils::log_error(err, e); } } diff --git a/lib/structs/responses/sync.cpp b/lib/structs/responses/sync.cpp index 347c764a1aee676254a29193a569d2f7a49268b5..cc086e0465b718d4a1d70d7d6e2391b7935b7dc0 100644 --- a/lib/structs/responses/sync.cpp +++ b/lib/structs/responses/sync.cpp @@ -5,6 +5,7 @@ #include <nlohmann/json.hpp> +#include <algorithm> #include <variant> using json = nlohmann::json; @@ -157,11 +158,38 @@ from_json(const json &obj, Rooms &rooms) void from_json(const json &obj, DeviceLists &device_lists) { - if (obj.count("changed") != 0) + if (obj.count("changed") != 0) { device_lists.changed = obj.at("changed").get<std::vector<std::string>>(); - if (obj.count("left") != 0) + device_lists.changed.erase( + std::remove_if(device_lists.changed.begin(), + device_lists.changed.end(), + [](const std::string &user) { + if (user.size() > 255) { + mtx::utils::log::log()->warn( + "Invalid userid in device list changed."); + return true; + } else + return false; + }), + device_lists.changed.end()); + } + + if (obj.count("left") != 0) { device_lists.left = obj.at("left").get<std::vector<std::string>>(); + + device_lists.left.erase(std::remove_if(device_lists.left.begin(), + device_lists.left.end(), + [](const std::string &user) { + if (user.size() > 255) { + mtx::utils::log::log()->warn( + "Invalid userid in device list left."); + return true; + } else + return false; + }), + device_lists.left.end()); + } } void @@ -193,10 +221,17 @@ from_json(const json &obj, Sync &response) response.device_unused_fallback_key_types = fallback_keys->get<std::vector<std::string>>(); if (obj.count("presence") != 0 && obj.at("presence").contains("events")) { - response.presence = - obj.at("presence") - .at("events") - .get<std::vector<mtx::events::Event<mtx::events::presence::Presence>>>(); + const auto &events = obj.at("presence").at("events"); + response.presence.reserve(events.size()); + for (const auto &e : events) { + try { + response.presence.push_back( + e.get<mtx::events::Event<mtx::events::presence::Presence>>()); + } catch (std::exception &ex) { + mtx::utils::log::log()->warn( + "Error parsing presence event: {}, {}", ex.what(), e.dump(2)); + } + } } if (obj.count("account_data") != 0) {