##// END OF EJS Templates
revset: explicitely tag alias arguments for expansion...
Patrick Mezard -
r16771:2f3317d5 stable
parent child Browse files
Show More
@@ -1283,6 +1283,27 b' def optimize(x, small):'
1283 return w + wa, (op, x[1], ta)
1283 return w + wa, (op, x[1], ta)
1284 return 1, x
1284 return 1, x
1285
1285
1286 _aliasarg = ('func', ('symbol', '_aliasarg'))
1287 def _getaliasarg(tree):
1288 """If tree matches ('func', ('symbol', '_aliasarg'), ('string', X))
1289 return X, None otherwise.
1290 """
1291 if (len(tree) == 3 and tree[:2] == _aliasarg
1292 and tree[2][0] == 'string'):
1293 return tree[2][1]
1294 return None
1295
1296 def _checkaliasarg(tree, known=None):
1297 """Check tree contains no _aliasarg construct or only ones which
1298 value is in known. Used to avoid alias placeholders injection.
1299 """
1300 if isinstance(tree, tuple):
1301 arg = _getaliasarg(tree)
1302 if arg is not None and (not known or arg not in known):
1303 raise error.ParseError(_("not a function: %s") % '_aliasarg')
1304 for t in tree:
1305 _checkaliasarg(t, known)
1306
1286 class revsetalias(object):
1307 class revsetalias(object):
1287 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
1308 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
1288 args = None
1309 args = None
@@ -1299,7 +1320,9 b' class revsetalias(object):'
1299 self.tree = ('func', ('symbol', m.group(1)))
1320 self.tree = ('func', ('symbol', m.group(1)))
1300 self.args = [x.strip() for x in m.group(2).split(',')]
1321 self.args = [x.strip() for x in m.group(2).split(',')]
1301 for arg in self.args:
1322 for arg in self.args:
1302 value = value.replace(arg, repr(arg))
1323 # _aliasarg() is an unknown symbol only used separate
1324 # alias argument placeholders from regular strings.
1325 value = value.replace(arg, '_aliasarg(%r)' % (arg,))
1303 else:
1326 else:
1304 self.name = name
1327 self.name = name
1305 self.tree = ('symbol', name)
1328 self.tree = ('symbol', name)
@@ -1307,6 +1330,8 b' class revsetalias(object):'
1307 self.replacement, pos = parse(value)
1330 self.replacement, pos = parse(value)
1308 if pos != len(value):
1331 if pos != len(value):
1309 raise error.ParseError(_('invalid token'), pos)
1332 raise error.ParseError(_('invalid token'), pos)
1333 # Check for placeholder injection
1334 _checkaliasarg(self.replacement, self.args)
1310
1335
1311 def _getalias(aliases, tree):
1336 def _getalias(aliases, tree):
1312 """If tree looks like an unexpanded alias, return it. Return None
1337 """If tree looks like an unexpanded alias, return it. Return None
@@ -1327,13 +1352,14 b' def _getalias(aliases, tree):'
1327 return None
1352 return None
1328
1353
1329 def _expandargs(tree, args):
1354 def _expandargs(tree, args):
1330 """Replace all occurences of ('string', name) with the
1355 """Replace _aliasarg instances with the substitution value of the
1331 substitution value of the same name in args, recursively.
1356 same name in args, recursively.
1332 """
1357 """
1333 if not isinstance(tree, tuple):
1358 if not tree or not isinstance(tree, tuple):
1334 return tree
1359 return tree
1335 if len(tree) == 2 and tree[0] == 'string':
1360 arg = _getaliasarg(tree)
1336 return args.get(tree[1], tree)
1361 if arg is not None:
1362 return args[arg]
1337 return tuple(_expandargs(t, args) for t in tree)
1363 return tuple(_expandargs(t, args) for t in tree)
1338
1364
1339 def _expandaliases(aliases, tree, expanding):
1365 def _expandaliases(aliases, tree, expanding):
@@ -1367,6 +1393,7 b' def _expandaliases(aliases, tree, expand'
1367 return result
1393 return result
1368
1394
1369 def findaliases(ui, tree):
1395 def findaliases(ui, tree):
1396 _checkaliasarg(tree)
1370 aliases = {}
1397 aliases = {}
1371 for k, v in ui.configitems('revsetalias'):
1398 for k, v in ui.configitems('revsetalias'):
1372 alias = revsetalias(k, v)
1399 alias = revsetalias(k, v)
@@ -558,6 +558,19 b' far away.'
558 abort: unknown revision '$1'!
558 abort: unknown revision '$1'!
559 [255]
559 [255]
560
560
561 $ echo 'injectparamasstring2 = max(_aliasarg("$1"))' >> .hg/hgrc
562 $ echo 'callinjection2($1) = descendants(injectparamasstring2)' >> .hg/hgrc
563 $ try 'callinjection2(2:5)'
564 (func
565 ('symbol', 'callinjection2')
566 (range
567 ('symbol', '2')
568 ('symbol', '5')))
569 hg: parse error: not a function: _aliasarg
570 [255]
571 >>> data = file('.hg/hgrc', 'rb').read()
572 >>> file('.hg/hgrc', 'wb').write(data.replace('_aliasarg', ''))
573
561 $ try 'd(2:5)'
574 $ try 'd(2:5)'
562 (func
575 (func
563 ('symbol', 'd')
576 ('symbol', 'd')
General Comments 0
You need to be logged in to leave comments. Login now