[PATCH] Check user supplied date format before accepting it

Matt Mackall mpm at selenic.com
Sat Aug 20 02:17:13 CDT 2005


On Mon, Jul 25, 2005 at 01:33:07PM +0200, Samuel Tardieu wrote:
> >>>>> "Sam" == Samuel Tardieu <sam at rfc1149.net> writes:
> 
> Sam> Without this patch, Mercurial accepts any date supplied by the
> Sam> user but is later unable to use it. This patch checks the
> Sam> validity of the date.
> 
> This patch is better (to be combined with the daylight saving time
> patch I sent earlier) as it accepts a broader range of dates.

Sorry I'm so far behind here. This looks mostly good, but a couple
comments. Please resend this after 0.6c comes out.

> # HG changeset patch
> # User Samuel Tardieu <sam at rfc1149.net>
> # Node ID 41440890e57d2dbacde03a2a114e5114a031ea4a
> # Parent  f9fa7a34575f6b71cdc900e9b560d38ddeb1a304
> Parse various date formats when accepting user specified dates
> 
> diff -r f9fa7a34575f -r 41440890e57d mercurial/util.py
> --- a/mercurial/util.py	Mon Jul 25 11:23:28 2005
> +++ b/mercurial/util.py	Mon Jul 25 11:24:15 2005
> @@ -7,7 +7,7 @@
>  
>  import os, errno
>  from demandload import *
> -demandload(globals(), "re")
> +demandload(globals(), "hg re time")

util shouldn't import hg.

>  
>  def unique(g):
>      seen = {}
> @@ -208,3 +208,35 @@
>                  return _readlock_file(pathname)
>              else:
>                  raise
> +
> +_date_fmt = None
> +_formats = ['%Y-%m-%d %H:%M:%S %Z', '%Y-%m-%d %H:%M:%S %z', '%Y-%m-%d %H:%M:%S']

Please wrap lines at < 80 columns. And generally don't use the module
scope namespace unless you have to - define this inside date_parser.

> +
> +def date_parser (date):
> +    global _date_fmt
> +    # Check whether it is already in the right format
> +    if valid_date_format(date): return date
> +    # Use a consistent format if one has been chosen already
> +    if _date_fmt:
> +        try: return "%f %d" % (time.mktime(time.strptime(date)), time.timezone)
> +        except: raise RepoError("date format is ambiguous")
> +    # Try to find a matching format
> +    for f in _formats:
> +        try:
> +            d = time.strptime(date, f)
> +            _date_fmt = f
> +            return "%f %d" % (time.mktime(d), time.timezone)
> +        except: pass

Best to avoid unqualified except statements, they can hide real bugs
quite well.

> +    # We could not find a satisfying one
> +    raise hg.RepoError("invalid date `%s'" % date)
> +    
> +def valid_date_format(date):
> +    words = date.split()
> +    if len(words) != 2: return False
> +    try:
> +        float(words[0])
> +        int(words[1])
> +        return True
> +    except:
> +        return False
> +

Use except TypeError here.

-- 
Mathematics is the supreme nostalgia of our time.


More information about the Mercurial mailing list