Merge pull request #8406 from s-hadinger/mqtt_escape_json

Add rule length, truncates rules too long and add escape JSON
This commit is contained in:
Theo Arends 2020-05-10 15:36:25 +02:00 committed by GitHub
commit aadfff1c0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 2 deletions

View File

@ -1863,3 +1863,62 @@ void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32
}
AddLog(loglevel);
}
/*********************************************************************************************\
* JSON parsing
\*********************************************************************************************/
// does the character needs to be escaped, and if so with which character
char escapeJSONChar(char c) {
if ((c == '\"') || (c == '\\')) {
return c;
}
if (c == '\n') { return 'n'; }
if (c == '\t') { return 't'; }
if (c == '\r') { return 'r'; }
if (c == '\f') { return 'f'; }
if (c == '\b') { return 'b'; }
return 0;
}
String escapeJSONString(const char *str) {
String r("");
if (nullptr == str) { return r; }
bool needs_escape = false;
size_t len_out = 1;
const char * c = str;
while (*c) {
if (escapeJSONChar(*c)) {
len_out++;
needs_escape = true;
}
c++;
len_out++;
}
if (needs_escape) {
// we need to escape some chars
// allocate target buffer
r.reserve(len_out);
c = str;
char *d = r.begin();
while (*c) {
char c2 = escapeJSONChar(*c);
if (c2) {
c++;
*d++ = '\\';
*d++ = c2;
} else {
*d++ = *c++;
}
}
*d = 0; // add NULL terminator
r = (char*) r.begin(); // assign the buffer to the string
} else {
r = str;
}
return r;
}

View File

@ -1992,12 +1992,21 @@ void CmndRule(void)
}
Rules.triggers[index -1] = 0; // Reset once flag
}
String rule = GetRule(index - 1);
size_t rule_len = rule.length();
if (rule_len >= MAX_RULE_SIZE) {
// we need to split the rule in chunks
rule = rule.substring(0, MAX_RULE_SIZE);
rule += F("...");
}
// snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"),
// XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)),
// GetStateText(bitRead(Settings.rule_stop, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]);
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"),
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Length\":%d,\"Free\":%d,\"Rules\":\"%s\"}"),
XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)),
GetStateText(bitRead(Settings.rule_stop, index -1)), sizeof(Settings.rules[0]) - GetRuleLenStorage(index - 1), GetRule(index - 1).c_str());
GetStateText(bitRead(Settings.rule_stop, index -1)),
rule_len, MAX_RULE_SIZE - GetRuleLenStorage(index - 1),
escapeJSONString(rule.c_str()).c_str());
}
}