Skip to content

Commit

Permalink
mqtt: Use string lengths not JSON struct sizes for payload limits.
Browse files Browse the repository at this point in the history
  • Loading branch information
rtrbt committed Mar 21, 2022
1 parent 4f3c236 commit b063b3b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
39 changes: 39 additions & 0 deletions software/src/config.cpp
Expand Up @@ -18,6 +18,7 @@
*/

#include "config.h"
#include "math.h"

struct printer {
void operator()(const Config::ConfString &x) const { Serial.println("string"); }
Expand Down Expand Up @@ -167,6 +168,40 @@ struct to_json {
const std::vector<String> &keys_to_censor;
};

struct string_length_visitor {
size_t operator()(const Config::ConfString &x) {
return x.maxChars + 3; // "" and null terminator
}
size_t operator()(const Config::ConfFloat &x) {
return 42; // Educated guess
}
size_t operator()(const Config::ConfInt &x) {
return 11;
}
size_t operator()(const Config::ConfUint &x) {
return 10;
}
size_t operator()(const Config::ConfBool &x) {
return 5;
}
size_t operator()(std::nullptr_t x) {
return 4;
}
size_t operator()(const Config::ConfArray &x)
{
return strict_variant::apply_visitor(string_length_visitor{}, x.prototype->value) * x.maxElements + (x.maxElements + 1); //[,] and n-1 ,
}
size_t operator()(const Config::ConfObject &x)
{
size_t sum = 2; // { and }
for (size_t i = 0; i < x.value.size(); ++i) {
sum += x.value[i].first.length() + 3; // "" and null terminator
sum += strict_variant::apply_visitor(string_length_visitor{}, x.value[i].second.value);;
}
return sum;
}
};

struct json_length_visitor {
size_t operator()(const Config::ConfString &x) {
return zero_copy ? 0 : (x.maxChars + 1);
Expand Down Expand Up @@ -692,6 +727,10 @@ size_t Config::json_size(bool zero_copy) const {
return strict_variant::apply_visitor(json_length_visitor{zero_copy}, value);
}

size_t Config::max_string_length() const {
return strict_variant::apply_visitor(string_length_visitor{}, value);
}

void Config::save_to_file(File file)
{
DynamicJsonDocument doc(json_size(false));
Expand Down
1 change: 1 addition & 0 deletions software/src/config.h
Expand Up @@ -380,6 +380,7 @@ struct Config {
}
*/
size_t json_size(bool zero_copy) const;
size_t max_string_length() const;

void save_to_file(File file);

Expand Down
4 changes: 2 additions & 2 deletions software/src/modules/mqtt/mqtt.cpp
Expand Up @@ -73,7 +73,7 @@ void Mqtt::subscribe(String topic_suffix, uint32_t max_payload_length, std::func

void Mqtt::addCommand(size_t commandIdx, const CommandRegistration &reg)
{
auto req_size = reg.config->json_size(true);
auto req_size = reg.config->max_string_length();
if (req_size > MQTT_RECV_BUFFER_SIZE) {
logger.printfln("MQTT: Recv buf is %u bytes. %s requires %u. Bump MQTT_RECV_BUFFER_SIZE! Not subscribing!", MQTT_RECV_BUFFER_SIZE, reg.path.c_str(), req_size);
return;
Expand All @@ -84,7 +84,7 @@ void Mqtt::addCommand(size_t commandIdx, const CommandRegistration &reg)
if (mqtt_state.get("connection_state")->asInt() != (int)MqttConnectionState::CONNECTED)
return;

subscribe(reg.path, reg.config->json_size(true), [reg, commandIdx](char *payload, size_t payload_len){
subscribe(reg.path, reg.config->max_string_length(), [reg, commandIdx](char *payload, size_t payload_len){
String reason = api.getCommandBlockedReason(commandIdx);
if (reason != "") {
logger.printfln("MQTT: Command %s is blocked: %s", reg.path.c_str(), reason.c_str());
Expand Down

0 comments on commit b063b3b

Please sign in to comment.