[2.0.x] Buffer overflow and scroll fix, UTF8 cleanup (#10844)
This commit is contained in:
committed by
Scott Lahteine
parent
235facd545
commit
6f330f397e
@ -80,7 +80,7 @@
|
||||
#else
|
||||
#define MAX_MESSAGE_LENGTH CHARSIZE * 2 * (LCD_WIDTH)
|
||||
#endif
|
||||
uint8_t status_scroll_pos = 0;
|
||||
uint8_t status_scroll_offset = 0;
|
||||
#else
|
||||
#define MAX_MESSAGE_LENGTH CHARSIZE * (LCD_WIDTH)
|
||||
#endif
|
||||
@ -5360,30 +5360,8 @@ void lcd_update() {
|
||||
} // ELAPSED(ms, next_lcd_update_ms)
|
||||
}
|
||||
|
||||
inline void pad_message_string() {
|
||||
uint8_t i = 0, j = 0;
|
||||
char c;
|
||||
lcd_status_message[MAX_MESSAGE_LENGTH] = '\0';
|
||||
while ((c = lcd_status_message[i]) && j < LCD_WIDTH) {
|
||||
if (PRINTABLE(c)) j++;
|
||||
i++;
|
||||
}
|
||||
if (true
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
&& j < LCD_WIDTH
|
||||
#endif
|
||||
) {
|
||||
// pad with spaces to fill up the line
|
||||
while (j++ < LCD_WIDTH) lcd_status_message[i++] = ' ';
|
||||
// chop off at the edge
|
||||
lcd_status_message[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_finishstatus(const bool persist=false) {
|
||||
|
||||
pad_message_string();
|
||||
|
||||
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
|
||||
UNUSED(persist);
|
||||
#endif
|
||||
@ -5401,7 +5379,7 @@ void lcd_finishstatus(const bool persist=false) {
|
||||
#endif
|
||||
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
status_scroll_pos = 0;
|
||||
status_scroll_offset = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5413,7 +5391,26 @@ bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); }
|
||||
|
||||
void lcd_setstatus(const char * const message, const bool persist) {
|
||||
if (lcd_status_message_level > 0) return;
|
||||
strncpy(lcd_status_message, message, MAX_MESSAGE_LENGTH);
|
||||
|
||||
// Here we have a problem. The message is encoded in UTF8, so
|
||||
// arbitrarily cutting it will be a problem. We MUST be sure
|
||||
// that there is no cutting in the middle of a multibyte character!
|
||||
|
||||
// Get a pointer to the null terminator
|
||||
const char* pend = message + strlen(message);
|
||||
|
||||
// If length of supplied UTF8 string is greater than
|
||||
// our buffer size, start cutting whole UTF8 chars
|
||||
while ((pend - message) > MAX_MESSAGE_LENGTH) {
|
||||
--pend;
|
||||
while (!START_OF_UTF8_CHAR(*pend)) --pend;
|
||||
};
|
||||
|
||||
// At this point, we have the proper cut point. Use it
|
||||
uint8_t maxLen = pend - message;
|
||||
strncpy(lcd_status_message, message, maxLen);
|
||||
lcd_status_message[maxLen] = '\0';
|
||||
|
||||
lcd_finishstatus(persist);
|
||||
}
|
||||
|
||||
@ -5421,7 +5418,26 @@ void lcd_setstatusPGM(const char * const message, int8_t level) {
|
||||
if (level < 0) level = lcd_status_message_level = 0;
|
||||
if (level < lcd_status_message_level) return;
|
||||
lcd_status_message_level = level;
|
||||
strncpy_P(lcd_status_message, message, MAX_MESSAGE_LENGTH);
|
||||
|
||||
// Here we have a problem. The message is encoded in UTF8, so
|
||||
// arbitrarily cutting it will be a problem. We MUST be sure
|
||||
// that there is no cutting in the middle of a multibyte character!
|
||||
|
||||
// Get a pointer to the null terminator
|
||||
const char* pend = message + strlen_P(message);
|
||||
|
||||
// If length of supplied UTF8 string is greater than
|
||||
// our buffer size, start cutting whole UTF8 chars
|
||||
while ((pend - message) > MAX_MESSAGE_LENGTH) {
|
||||
--pend;
|
||||
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend;
|
||||
};
|
||||
|
||||
// At this point, we have the proper cut point. Use it
|
||||
uint8_t maxLen = pend - message;
|
||||
strncpy_P(lcd_status_message, message, maxLen);
|
||||
lcd_status_message[maxLen] = '\0';
|
||||
|
||||
lcd_finishstatus(level > 0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user