All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3/3] make path_combine() especially for	filenames, not URLs
Date: Fri, 21 Jan 2011 11:07:27 +0100	[thread overview]
Message-ID: <4D395ADF.5060102@redhat.com> (raw)
In-Reply-To: <1294829822-27938-4-git-send-email-mjt@msgid.tls.msk.ru>

Am 12.01.2011 11:57, schrieb Michael Tokarev:
> Currently the two routines tries to "understand" and skip <protocol>:
> prefix in path arguments are path_combine() and path_is_absolute()
> (the latter isn't used anywhere but in the former).  This is wrong,
> since notion of absolute path is, at least, protocol-specific.
> 
> The implementation is more wrong on windows where even non-absolute
> paths but with drive name (d:foo) should be treated as absolute, as
> in, one can't combine, say, c:\bar with d:foo forming c:\foo as
> path_combine() currently does.
> 
> Introduce isslash() macro that works correctly on both windows and
> unix, use it in is_windows_drive_prefix() (since any form of slash
> can be used in constructs like //./), 

You're saying that \/.\ is a valid format for it? Wow...

> remove path_is_absolute() and
> hardcode the trivial (but right) condition in path_combine(), and
> simplify path_combine() further by removing <protocol>: handling
> and unifying shash searching.
> 
> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> ---
>  block.c |   72 +++++++++++++++++++++-----------------------------------------
>  1 files changed, 25 insertions(+), 47 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 42d6ff1..31a821d 100644
> --- a/block.c
> +++ b/block.c
> @@ -71,6 +71,9 @@ static BlockDriverState *bs_snapshots;
>  static int use_bdrv_whitelist;
>  
>  #ifdef _WIN32
> +
> +#define isslash(c) ((c) == '/' || (c) == '\\')
> +
>  static int is_windows_drive_prefix(const char *filename)
>  {
>      return (((filename[0] >= 'a' && filename[0] <= 'z') ||
> @@ -83,11 +86,17 @@ int is_windows_drive(const char *filename)
>      if (is_windows_drive_prefix(filename) &&
>          filename[2] == '\0')
>          return 1;
> -    if (strstart(filename, "\\\\.\\", NULL) ||
> -        strstart(filename, "//./", NULL))
> -        return 1;
> +    if (isslash(filename[0] && isslash(filename[1]) &&

Missing bracket, doesn't even compile.

> +        filename[2] == '.' &&  isslash(filename[3]))
> +        return 1; /* special case: windows device "//./" */

Please add curly braces.

>      return 0;
>  }
> +
> +#else
> +
> +#define isslash(c) ((c) == '/')
> +#define is_windows_drive_prefix(filename) (0)

Please make this a function, for consistency and type checking. The
compiler is going to inline it anyway.

> +
>  #endif
>  
>  /* check if the path starts with "<protocol>:"
> @@ -115,61 +124,30 @@ static char *path_has_protocol(const char *path)
>              (char*)p : NULL;
>  }
>  
> -int path_is_absolute(const char *path)
> -{
> -    const char *p;
> -#ifdef _WIN32
> -    /* specific case for names like: "\\.\d:" */
> -    if (*path == '/' || *path == '\\')
> -        return 1;
> -#endif
> -    p = strchr(path, ':');
> -    if (p)
> -        p++;
> -    else
> -        p = path;
> -#ifdef _WIN32
> -    return (*p == '/' || *p == '\\');
> -#else
> -    return (*p == '/');
> -#endif
> -}
> -
>  /* if filename is absolute, just copy it to dest. Otherwise, build a
> -   path to it by considering it is relative to base_path. URL are
> -   supported. */
> +   path to it by considering it is relative to base_path.
> +   This is really about filenames not URLs - we don't support
> +   <protocol>: prefix in filename since it makes no sense, especially
> +   if the protocol in base_path is not the same as in filename.
> + */
>  void path_combine(char *dest, int dest_size,
>                    const char *base_path,
>                    const char *filename)
>  {
> -    const char *p, *p1;
> +    const char *p;
>      int len;
>  
>      if (dest_size <= 0)
>          return;
> -    if (path_is_absolute(filename)) {
> +    /* on windows, d:filename should be treated as absolute too */
> +    if (isslash(filename[0]) || is_windows_drive_prefix(filename)) {
>          pstrcpy(dest, dest_size, filename);
>      } else {
> -        p = strchr(base_path, ':');
> -        if (p)
> -            p++;
> -        else
> -            p = base_path;
> -        p1 = strrchr(base_path, '/');
> -#ifdef _WIN32
> -        {
> -            const char *p2;
> -            p2 = strrchr(base_path, '\\');
> -            if (!p1 || p2 > p1)
> -                p1 = p2;
> -        }
> -#endif
> -        if (p1)
> -            p1++;
> -        else
> -            p1 = base_path;
> -        if (p1 > p)
> -            p = p1;
> +        /* find last slash */
> +        p = base_path + strlen(base_path);
> +        while(p >= base_path && !isslash(*p))
> +            --p;
> +        p++;

Please add braces.

>          len = p - base_path;
>          if (len > dest_size - 1)
>              len = dest_size - 1;

This changes the semantics to throw away the protocol. For example
fat:foo combined with bar would have resulted in fat:bar previously  and
results in bar now.

Probably not a problem. path_combine gets even worse if filename has a
protocol. It's completely unclear what it's supposed to do with
protocols anyway.

Kevin

      reply	other threads:[~2011-01-21 10:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1294829822-27938-1-git-send-email-mjt@tls.msk.ru>
2011-01-12 10:57 ` [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool Michael Tokarev
2011-01-21  9:29   ` Kevin Wolf
2011-01-12 10:57 ` [Qemu-devel] [PATCH 2/3] use new path_has_protocol() in bdrv_find_protocol() Michael Tokarev
2011-01-12 10:57 ` [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs Michael Tokarev
2011-01-21 10:07   ` Kevin Wolf [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D395ADF.5060102@redhat.com \
    --to=kwolf@redhat.com \
    --cc=mjt@tls.msk.ru \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.