If this is a valid plugin return full path name, otherwise NULL */
| 1579 | |
| 1580 | /* If this is a valid plugin return full path name, otherwise NULL */ |
| 1581 | static const char *plugin_fullpath(const tal_t *ctx, const char *dir, |
| 1582 | const char *basename) |
| 1583 | { |
| 1584 | struct stat st; |
| 1585 | const char *fullname; |
| 1586 | struct utf8_state utf8 = UTF8_STATE_INIT; |
| 1587 | |
| 1588 | for (size_t i = 0; basename[i]; i++) { |
| 1589 | if (!utf8_decode(&utf8, basename[i])) |
| 1590 | continue; |
| 1591 | /* Not valid UTF8? Let's not go there... */ |
| 1592 | if (errno != 0) |
| 1593 | return NULL; |
| 1594 | if (utf8.used_len != 1) |
| 1595 | continue; |
| 1596 | if (!cispunct(utf8.c)) |
| 1597 | continue; |
| 1598 | if (utf8.c != '-' && utf8.c != '_' && utf8.c != '.') |
| 1599 | return NULL; |
| 1600 | } |
| 1601 | |
| 1602 | fullname = path_join(ctx, dir, basename); |
| 1603 | if (stat(fullname, &st) != 0) |
| 1604 | return tal_free(fullname); |
| 1605 | /* Only regular files please (or symlinks to such: stat not lstat!) */ |
| 1606 | if ((st.st_mode & S_IFMT) != S_IFREG) |
| 1607 | return tal_free(fullname); |
| 1608 | /* Must be executable by someone. */ |
| 1609 | if (!(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) |
| 1610 | return tal_free(fullname); |
| 1611 | |
| 1612 | /* Someone actually runs this on NTFS, where everything apparently is |
| 1613 | * executable! This prevents the most obvious damage. */ |
| 1614 | if (streq(basename, "README.md")) |
| 1615 | return tal_free(fullname); |
| 1616 | |
| 1617 | return fullname; |
| 1618 | } |
| 1619 | |
| 1620 | char *add_plugin_dir(struct plugins *plugins, const char *dir, bool error_ok) |
| 1621 | { |
no test coverage detected