Re: [PATCH v4 6/8] dir: fix checks on common prefix directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 18, 2019 at 1:29 PM Junio C Hamano <gitster@xxxxxxxxx> wrote:
>
> "Elijah Newren via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes:
>
...
> >       while (len && path[len - 1] == '/')
> >               len--;
> >       if (!len)
> >               return 1;
> > +
> > +     de = xcalloc(1, sizeof(struct dirent)+len+1);
>
> That "+len+1" may deserve a comment?

Good point, I'll add one and send a re-roll.

>  If we wanted to shoot for the
> minimum memory consumption (and we do not), we would probably
> allocate
>
>         (sizeof(struct dirent) - sizeof(de->d_name)) +
>                 max(sizeof(de->d_name), len + 1)
>
> bytes, but unconditionally adding len+1 is simpler and easier to
> understand.  Either way, we *are* relying on the assumption that
> either:
>
>  (1) the "struct dirent" would have d_name[] array at the end of the
>      struct, and by over-allocating, we can safely fit and carry a
>      name that is much longer than sizeof(.d_name[]); OR
>
>  (2) the "struct dirent" has d_name[] that is large enough to hold len+1
>      bytes, if the assumption (1) does not hold.
>
> is true.
>
> > +     memset(&cdir, 0, sizeof(cdir));
> > +     cdir.de = de;
> > +#if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
> > +     de->d_type = DT_DIR;
> > +#endif
> >       baselen = 0;
> > +     prevlen = 0;
> >       while (1) {
> > -             cp = path + baselen + !!baselen;
> > +             prevlen = baselen + !!baselen;
> > +             cp = path + prevlen;
> >               cp = memchr(cp, '/', path + len - cp);
> >               if (!cp)
> >                       baselen = len;
> >               else
> >                       baselen = cp - path;
> > -             strbuf_setlen(&sb, 0);
> > +             strbuf_reset(&sb);
> >               strbuf_add(&sb, path, baselen);
> >               if (!is_directory(sb.buf))
> >                       break;
>
>
>
> > -             if (simplify_away(sb.buf, sb.len, pathspec))
> > -                     break;
> > -             if (treat_one_path(dir, NULL, istate, &sb, baselen, pathspec,
> > -                                DT_DIR, NULL) == path_none)
> > +             strbuf_reset(&sb);
> > +             strbuf_add(&sb, path, prevlen);
> > +             memcpy(de->d_name, path+prevlen, baselen-prevlen);
> > +             de->d_name[baselen-prevlen] = '\0';
> > +             state = treat_path(dir, NULL, &cdir, istate, &sb, prevlen,
> > +                                 pathspec);
>
> So this is the crux fo the fix---instead of doing a (poor) imitation
> of what treat_path() does by calling simplify_away() and
> treat_one_path() ourselves, we make a call to the real thing.
>
> Looking good.  Thanks.



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux