parse_index2: fix crash on bad argument type (
issue4110)
Passing a non-string to parsers.parse_index2() causes Mercurial to crash
instead of raising a TypeError (found on Mac OS X 10.8.5, Python 2.7.6):
import mercurial.parsers as parsers
parsers.parse_index2(0, 0)
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 parsers.so 0x
000000010e071c59 _index_clearcaches + 73 (parsers.c:644)
1 parsers.so 0x
000000010e06f2d5 index_dealloc + 21 (parsers.c:1767)
2 parsers.so 0x
000000010e074e3b parse_index2 + 347 (parsers.c:1891)
3 org.python.python 0x
000000010dda8b17 PyEval_EvalFrameEx + 9911
This happens because when arguments of the wrong type are passed to
parsers.parse_index2(), indexType's initialization function index_init() in
parsers.c leaves the indexObject instance in a state that indexType's
destructor function index_dealloc() cannot handle.
This patch moves enough of the indexObject initialization code inside
index_init() from after the argument validation code to before it.
This way, when bad arguments are passed to index_init(), the destructor
doesn't crash and the existing code to raise a TypeError works. This
patch also adds a test to check that a TypeError is raised.
# Mercurial extension to provide the 'hg children' command
#
# Copyright 2007 by Intevation GmbH <intevation@intevation.de>
#
# Author(s):
# Thomas Arendsen Hein <thomas@intevation.de>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''command to display child changesets (DEPRECATED)
This extension is deprecated. You should use :hg:`log -r
"children(REV)"` instead.
'''
from mercurial import cmdutil, commands
from mercurial.commands import templateopts
from mercurial.i18n import _
testedwith = 'internal'
def children(ui, repo, file_=None, **opts):
"""show the children of the given or working directory revision
Print the children of the working directory's revisions. If a
revision is given via -r/--rev, the children of that revision will
be printed. If a file argument is given, revision in which the
file was last changed (after the working directory revision or the
argument to --rev if given) is printed.
"""
rev = opts.get('rev')
if file_:
ctx = repo.filectx(file_, changeid=rev)
else:
ctx = repo[rev]
displayer = cmdutil.show_changeset(ui, repo, opts)
for cctx in ctx.children():
displayer.show(cctx)
displayer.close()
cmdtable = {
"children":
(children,
[('r', 'rev', '',
_('show children of the specified revision'), _('REV')),
] + templateopts,
_('hg children [-r REV] [FILE]')),
}
commands.inferrepo += " children"