comparison mcabber/mcabber/commands.c @ 2315:1cfe6df4f7e6

Improve load_message_from_file() file content validation
author Mikael Berthe <mikael@lilotux.net>
date Thu, 11 May 2017 14:35:35 +0200
parents def5f64c253d
children a62bbd4d7061
comparison
equal deleted inserted replaced
2314:0d5660c6b4aa 2315:1cfe6df4f7e6
1541 { 1541 {
1542 FILE *fd; 1542 FILE *fd;
1543 struct stat buf; 1543 struct stat buf;
1544 char *msgbuf, *msgbuf_utf8; 1544 char *msgbuf, *msgbuf_utf8;
1545 char *p; 1545 char *p;
1546 char *next_utf8_char; 1546 gboolean valid;
1547 size_t len; 1547 size_t len;
1548 1548
1549 fd = fopen(filename, "r"); 1549 fd = fopen(filename, "r");
1550 1550
1551 if (!fd || fstat(fileno(fd), &buf)) { 1551 if (!fd || fstat(fileno(fd), &buf)) {
1563 1563
1564 msgbuf = g_new0(char, HBB_BLOCKSIZE); 1564 msgbuf = g_new0(char, HBB_BLOCKSIZE);
1565 len = fread(msgbuf, 1, HBB_BLOCKSIZE-1, fd); 1565 len = fread(msgbuf, 1, HBB_BLOCKSIZE-1, fd);
1566 fclose(fd); 1566 fclose(fd);
1567 1567
1568 next_utf8_char = msgbuf;
1569
1570 // Check there is no binary data. It must be a *message* file! 1568 // Check there is no binary data. It must be a *message* file!
1571 for (p = msgbuf ; *p ; p++) { 1569 valid = TRUE;
1572 if (utf8_mode) { 1570 if (utf8_mode) {
1573 if (p == next_utf8_char) { 1571 valid = g_utf8_validate(msgbuf, len, (const gchar **)&p);
1574 if (!iswprint(get_char(p)) && *p != '\n' && *p != '\t') 1572 } else { // Non-UTF8
1573 for (p = msgbuf ; *p; p++) {
1574 if (!utf8_mode) {
1575 unsigned char sc = *p;
1576 if (!iswprint(sc) && sc != '\n' && sc != '\t') {
1577 valid = FALSE;
1575 break; 1578 break;
1576 next_utf8_char = next_char(p); 1579 }
1577 } 1580 }
1578 } else { 1581 }
1579 unsigned char sc = *p; 1582 }
1580 if (!iswprint(sc) && sc != '\n' && sc != '\t') 1583
1581 break; 1584 if (valid && (*p || p != len+msgbuf)) {
1582 } 1585 valid = FALSE; // We're not at the End Of Line...
1583 } 1586 }
1584 1587 if (!valid) {
1585 if (*p || (size_t)(p-msgbuf) != len) { // We're not at the End Of Line... 1588 scr_LogPrint(LPRINT_LOGNORM, "Message file contains "
1586 scr_LogPrint(LPRINT_LOGNORM, "Message file contains " 1589 "invalid characters (%s)", filename);
1587 "invalid characters (%s)", filename); 1590 g_free(msgbuf);
1588 g_free(msgbuf); 1591 return NULL;
1589 return NULL;
1590 } 1592 }
1591 1593
1592 // p is now at the EOL 1594 // p is now at the EOL
1593 // Let's strip trailing newlines 1595 // Let's strip trailing newlines
1594 if (p > msgbuf) 1596 if (p > msgbuf)