Mercurial > pidgin
comparison libpurple/plugins/log_reader.c @ 31753:d1ea32c41634
log_reader: strchr(), and some simplifying to make clang happier
Clang's static analyzer thought 'line' might result in a null deref
in the trillian log reader, if there was an empty "(Link: )" section
(temp would be NULL), except that couldn't ever happen, because the data
was *always* \n-terminated, so 'c' is alway non-NULL.
| author | Paul Aurich <paul@darkrain42.org> |
|---|---|
| date | Thu, 21 Jul 2011 05:36:54 +0000 |
| parents | a8cc50c2279f |
| children | 6d6056e176fe |
comparison
equal
deleted
inserted
replaced
| 31750:cb4705abb991 | 31753:d1ea32c41634 |
|---|---|
| 1452 { | 1452 { |
| 1453 const char *link; | 1453 const char *link; |
| 1454 const char *footer = NULL; | 1454 const char *footer = NULL; |
| 1455 GString *temp = NULL; | 1455 GString *temp = NULL; |
| 1456 | 1456 |
| 1457 if ((c = strstr(c, "\n"))) | 1457 /* The data is always terminated with a newline (see above) */ |
| 1458 { | 1458 c = strchr(c, '\n'); |
| 1459 *c = '\0'; | 1459 *c = '\0'; |
| 1460 c++; | 1460 c++; |
| 1461 } | |
| 1462 | 1461 |
| 1463 /* Convert links. | 1462 /* Convert links. |
| 1464 * | 1463 * |
| 1465 * The format is (Link: URL)URL | 1464 * The format is (Link: URL)URL |
| 1466 * So, I want to find each occurance of "(Link: " and replace that chunk with: | 1465 * So, I want to find each occurance of "(Link: " and replace that chunk with: |
| 1480 if (*link) | 1479 if (*link) |
| 1481 { | 1480 { |
| 1482 char *end_paren; | 1481 char *end_paren; |
| 1483 char *space; | 1482 char *space; |
| 1484 | 1483 |
| 1485 if (!(end_paren = strstr(link, ")"))) | 1484 if (!(end_paren = strchr(link, ')'))) |
| 1486 { | 1485 { |
| 1487 /* Something is not as we expect. Bail out. */ | 1486 /* Something is not as we expect. Bail out. */ |
| 1488 break; | 1487 break; |
| 1489 } | 1488 } |
| 1490 | 1489 |
| 1491 if (!temp) | 1490 if (!temp) |
| 1492 temp = g_string_sized_new(c ? (c - 1 - line) : strlen(line)); | 1491 temp = g_string_sized_new(strlen(line)); |
| 1493 | 1492 |
| 1494 g_string_append_len(temp, line, (tmp - line)); | 1493 g_string_append_len(temp, line, (tmp - line)); |
| 1495 | 1494 |
| 1496 /* Start an <a> tag. */ | 1495 /* Start an <a> tag. */ |
| 1497 g_string_append(temp, "<a href=\""); | 1496 g_string_append(temp, "<a href=\""); |
| 1502 /* Finish the <a> tag. */ | 1501 /* Finish the <a> tag. */ |
| 1503 g_string_append(temp, "\">"); | 1502 g_string_append(temp, "\">"); |
| 1504 | 1503 |
| 1505 /* The \r is a bit of a hack to keep there from being a \r in | 1504 /* The \r is a bit of a hack to keep there from being a \r in |
| 1506 * the link text, which may not matter. */ | 1505 * the link text, which may not matter. */ |
| 1507 if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r"))) | 1506 if ((space = strchr(end_paren, ' ')) || (space = strchr(end_paren, '\r'))) |
| 1508 { | 1507 { |
| 1509 g_string_append_len(temp, end_paren + 1, space - end_paren - 1); | 1508 g_string_append_len(temp, end_paren + 1, space - end_paren - 1); |
| 1510 | 1509 |
| 1511 /* Close the <a> tag. */ | 1510 /* Close the <a> tag. */ |
| 1512 g_string_append(temp, "</a>"); | 1511 g_string_append(temp, "</a>"); |
| 1537 } | 1536 } |
| 1538 | 1537 |
| 1539 if (*line == '[') { | 1538 if (*line == '[') { |
| 1540 const char *timestamp; | 1539 const char *timestamp; |
| 1541 | 1540 |
| 1542 if ((timestamp = strstr(line, "]"))) { | 1541 if ((timestamp = strchr(line, ']'))) { |
| 1543 line++; | 1542 line++; |
| 1544 /* TODO: Parse the timestamp and convert it to Purple's format. */ | 1543 /* TODO: Parse the timestamp and convert it to Purple's format. */ |
| 1545 g_string_append(formatted, "<font size=\"2\">("); | 1544 g_string_append(formatted, "<font size=\"2\">("); |
| 1546 g_string_append_len(formatted, line, (timestamp - line)); | 1545 g_string_append_len(formatted, line, (timestamp - line)); |
| 1547 g_string_append(formatted,")</font> "); | 1546 g_string_append(formatted,")</font> "); |
| 1656 "<span style=\"color: #A82F2F;\">" | 1655 "<span style=\"color: #A82F2F;\">" |
| 1657 "<b>%s</b></span>: ", alias); | 1656 "<b>%s</b></span>: ", alias); |
| 1658 } | 1657 } |
| 1659 } | 1658 } |
| 1660 } else { | 1659 } else { |
| 1661 const char *line2 = strstr(line, ":"); | 1660 const char *line2 = strchr(line, ':'); |
| 1662 if (line2) { | 1661 if (line2) { |
| 1663 const char *acct_name; | 1662 const char *acct_name; |
| 1664 line2++; | 1663 line2++; |
| 1665 line = line2; | 1664 line = line2; |
| 1666 acct_name = purple_account_get_alias(log->account); | 1665 acct_name = purple_account_get_alias(log->account); |
| 1826 char *tmp; | 1825 char *tmp; |
| 1827 | 1826 |
| 1828 new_line = c; | 1827 new_line = c; |
| 1829 | 1828 |
| 1830 /* find EOL */ | 1829 /* find EOL */ |
| 1831 c = strstr(c, "\n"); | 1830 c = strchr(c, '\n'); |
| 1832 c++; | 1831 c++; |
| 1833 | 1832 |
| 1834 /* Find the last '(' character. */ | 1833 /* Find the last '(' character. */ |
| 1835 if ((tmp = strstr(c, "\n")) != NULL) { | 1834 if ((tmp = strchr(c, '\n')) != NULL) { |
| 1836 while (*tmp && *tmp != '(') --tmp; | 1835 while (*tmp && *tmp != '(') --tmp; |
| 1837 c = tmp; | 1836 c = tmp; |
| 1838 } else { | 1837 } else { |
| 1839 while (*c) | 1838 while (*c) |
| 1840 c++; | 1839 c++; |
| 1902 start_log = new_line; | 1901 start_log = new_line; |
| 1903 } | 1902 } |
| 1904 | 1903 |
| 1905 if (*c) { | 1904 if (*c) { |
| 1906 /* find EOF */ | 1905 /* find EOF */ |
| 1907 c = strstr(c, "\n"); | 1906 c = strchr(c, '\n'); |
| 1908 c++; | 1907 c++; |
| 1909 } | 1908 } |
| 1910 } | 1909 } |
| 1911 | 1910 |
| 1912 g_free(contents); | 1911 g_free(contents); |
| 1981 const char *buddy_name; | 1980 const char *buddy_name; |
| 1982 | 1981 |
| 1983 is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC); | 1982 is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC); |
| 1984 | 1983 |
| 1985 /* find EOL */ | 1984 /* find EOL */ |
| 1986 c = strstr(c, "\n"); | 1985 c = strchr(c, '\n'); |
| 1987 | 1986 |
| 1988 /* XXX: Do we need buddy_name when we have buddy->alias? */ | 1987 /* XXX: Do we need buddy_name when we have buddy->alias? */ |
| 1989 buddy_name = ++c; | 1988 buddy_name = ++c; |
| 1990 | 1989 |
| 1991 /* Find the last '(' character. */ | 1990 /* Find the last '(' character. */ |
| 1992 if ((tmp = strstr(c, "\n")) != NULL) { | 1991 if ((tmp = strchr(c, '\n')) != NULL) { |
| 1993 while (*tmp && *tmp != '(') --tmp; | 1992 while (*tmp && *tmp != '(') --tmp; |
| 1994 c = tmp; | 1993 c = tmp; |
| 1995 } else { | 1994 } else { |
| 1996 while (*c) | 1995 while (*c) |
| 1997 c++; | 1996 c++; |
| 2040 "<span style=\"color: #16569E;\">" | 2039 "<span style=\"color: #16569E;\">" |
| 2041 "<b>%s</b></span>: ", acct_name); | 2040 "<b>%s</b></span>: ", acct_name); |
| 2042 } | 2041 } |
| 2043 | 2042 |
| 2044 /* find EOF */ | 2043 /* find EOF */ |
| 2045 c = strstr(c, "\n"); | 2044 c = strchr(c, '\n'); |
| 2046 line = ++c; | 2045 line = ++c; |
| 2047 } | 2046 } |
| 2048 } | 2047 } |
| 2049 } else { | 2048 } else { |
| 2050 if ((c = strstr(c, "\n"))) | 2049 if ((c = strchr(c, '\n'))) |
| 2051 *c = '\0'; | 2050 *c = '\0'; |
| 2052 | 2051 |
| 2053 if (line[0] != '\n' && line[0] != '\r') { | 2052 if (line[0] != '\n' && line[0] != '\r') { |
| 2054 | 2053 |
| 2055 g_string_append(formatted, line); | 2054 g_string_append(formatted, line); |
| 2184 " path = (%s)," | 2183 " path = (%s)," |
| 2185 " offset = (%d)," | 2184 " offset = (%d)," |
| 2186 " length = (%d)\n", | 2185 " length = (%d)\n", |
| 2187 sn, data->path, data->offset, data->length); | 2186 sn, data->path, data->offset, data->length); |
| 2188 } | 2187 } |
| 2189 c = strstr(c, "\n"); | 2188 c = strchr(c, '\n'); |
| 2190 c++; | 2189 c++; |
| 2191 } | 2190 } |
| 2192 | 2191 |
| 2193 /* I've seen the file end without the AMSN_LOG_CONV_END bit */ | 2192 /* I've seen the file end without the AMSN_LOG_CONV_END bit */ |
| 2194 if (found_start) { | 2193 if (found_start) { |
| 2340 start = contents; | 2339 start = contents; |
| 2341 while (start && *start) { | 2340 while (start && *start) { |
| 2342 char *end; | 2341 char *end; |
| 2343 char *old_tag; | 2342 char *old_tag; |
| 2344 char *tag; | 2343 char *tag; |
| 2345 end = strstr(start, "\n"); | 2344 end = strchr(start, '\n'); |
| 2346 if (!end) | 2345 if (!end) |
| 2347 break; | 2346 break; |
| 2348 *end = '\0'; | 2347 *end = '\0'; |
| 2349 if (purple_str_has_prefix(start, AMSN_LOG_FORMAT_TAG) && in_span) { | 2348 if (purple_str_has_prefix(start, AMSN_LOG_FORMAT_TAG) && in_span) { |
| 2350 /* New format for this line */ | 2349 /* New format for this line */ |
