On Sat, Jun 25, 2011 at 03:48:42PM +0200, Ingo Schwarze wrote:
> +static void
> +check_companion(char **orig) {
> + struct stat sb_orig, sb_comp;
> + size_t len;
> + char *p, *pext, comp[MAXPATHLEN];
> +
> + len = strlcpy(comp, *orig, sizeof(comp));
> + p = comp + len;
> +
> + /* Locate the file name extension. */
> + while (p > comp && *p != '.' && *p != '/')
> + p--;
> + if (*p == '.')
> + pext = p + 1;
> + else
> + return;
> +
> + /* Locate the last slash, the one before "page". */
> + while (p > comp && *p != '/')
> + p--;
> + if (--p <= comp)
> + return;
> +
> + /* Locate the previous slash, the one before {cat,man}. */
> + while (p > comp && *p != '/')
> + p--;
> + if (*p == '/')
> + p++;
> + else
> + return;
What about arch-dependent pages ? you have to go back until you find /manX
or /catX
> + /* Rewrite manN/page.N <-> catN/page.0. */
> + if (!strncmp(p, "man", 3)) {
> + memcpy(p, "cat", 3);
> + *pext++ = '0';
> + } else if (!strncmp(p, "cat", 3)) {
> + memcpy(p, "man", 3);
> + p += 3;
> + while (*p != '/')
> + *pext++ = *p++;
buffer overflow right here. strlen("0") < strlen("3p")
> + } else
> + return;
> + *pext = '\0';
> +