##// END OF EJS Templates
revset: use decorator to mark a predicate as safe...
FUJIWARA Katsunori -
r27587:c8dc4801 default
parent child Browse files
Show More
@@ -474,6 +474,11 b' def func(repo, subset, a, b):'
474 # x - argument in tree form
474 # x - argument in tree form
475 symbols = {}
475 symbols = {}
476
476
477 # symbols which can't be used for a DoS attack for any given input
478 # (e.g. those which accept regexes as plain strings shouldn't be included)
479 # functions that just return a lot of changesets (like all) don't count here
480 safesymbols = set()
481
477 class predicate(registrar.funcregistrar):
482 class predicate(registrar.funcregistrar):
478 """Decorator to register revset predicate
483 """Decorator to register revset predicate
479
484
@@ -495,6 +500,16 b' class predicate(registrar.funcregistrar)'
495 formatdoc = "``%s``\n %s"
500 formatdoc = "``%s``\n %s"
496 getname = registrar.funcregistrar.parsefuncdecl
501 getname = registrar.funcregistrar.parsefuncdecl
497
502
503 def __init__(self, decl, safe=False):
504 """'safe' indicates whether a predicate is safe for DoS attack
505 """
506 super(predicate, self).__init__(decl)
507 self.safe = safe
508
509 def extraaction(self, name, func):
510 if self.safe:
511 safesymbols.add(name)
512
498 class extpredicate(registrar.delayregistrar):
513 class extpredicate(registrar.delayregistrar):
499 """Decorator to register revset predicate in extensions
514 """Decorator to register revset predicate in extensions
500
515
@@ -529,7 +544,7 b' def _destmerge(repo, subset, x):'
529 getargs(x, 0, 0, _("_mergedefaultdest takes no arguments"))
544 getargs(x, 0, 0, _("_mergedefaultdest takes no arguments"))
530 return subset & baseset([destutil.destmerge(repo)])
545 return subset & baseset([destutil.destmerge(repo)])
531
546
532 @predicate('adds(pattern)')
547 @predicate('adds(pattern)', safe=True)
533 def adds(repo, subset, x):
548 def adds(repo, subset, x):
534 """Changesets that add a file matching pattern.
549 """Changesets that add a file matching pattern.
535
550
@@ -541,7 +556,7 b' def adds(repo, subset, x):'
541 pat = getstring(x, _("adds requires a pattern"))
556 pat = getstring(x, _("adds requires a pattern"))
542 return checkstatus(repo, subset, pat, 1)
557 return checkstatus(repo, subset, pat, 1)
543
558
544 @predicate('ancestor(*changeset)')
559 @predicate('ancestor(*changeset)', safe=True)
545 def ancestor(repo, subset, x):
560 def ancestor(repo, subset, x):
546 """A greatest common ancestor of the changesets.
561 """A greatest common ancestor of the changesets.
547
562
@@ -573,13 +588,13 b' def _ancestors(repo, subset, x, followfi'
573 s = _revancestors(repo, heads, followfirst)
588 s = _revancestors(repo, heads, followfirst)
574 return subset & s
589 return subset & s
575
590
576 @predicate('ancestors(set)')
591 @predicate('ancestors(set)', safe=True)
577 def ancestors(repo, subset, x):
592 def ancestors(repo, subset, x):
578 """Changesets that are ancestors of a changeset in set.
593 """Changesets that are ancestors of a changeset in set.
579 """
594 """
580 return _ancestors(repo, subset, x)
595 return _ancestors(repo, subset, x)
581
596
582 @predicate('_firstancestors')
597 @predicate('_firstancestors', safe=True)
583 def _firstancestors(repo, subset, x):
598 def _firstancestors(repo, subset, x):
584 # ``_firstancestors(set)``
599 # ``_firstancestors(set)``
585 # Like ``ancestors(set)`` but follows only the first parents.
600 # Like ``ancestors(set)`` but follows only the first parents.
@@ -602,7 +617,7 b' def ancestorspec(repo, subset, x, n):'
602 ps.add(r)
617 ps.add(r)
603 return subset & ps
618 return subset & ps
604
619
605 @predicate('author(string)')
620 @predicate('author(string)', safe=True)
606 def author(repo, subset, x):
621 def author(repo, subset, x):
607 """Alias for ``user(string)``.
622 """Alias for ``user(string)``.
608 """
623 """
@@ -611,7 +626,7 b' def author(repo, subset, x):'
611 kind, pattern, matcher = _substringmatcher(n)
626 kind, pattern, matcher = _substringmatcher(n)
612 return subset.filter(lambda x: matcher(encoding.lower(repo[x].user())))
627 return subset.filter(lambda x: matcher(encoding.lower(repo[x].user())))
613
628
614 @predicate('bisect(string)')
629 @predicate('bisect(string)', safe=True)
615 def bisect(repo, subset, x):
630 def bisect(repo, subset, x):
616 """Changesets marked in the specified bisect status:
631 """Changesets marked in the specified bisect status:
617
632
@@ -630,11 +645,11 b' def bisect(repo, subset, x):'
630
645
631 # Backward-compatibility
646 # Backward-compatibility
632 # - no help entry so that we do not advertise it any more
647 # - no help entry so that we do not advertise it any more
633 @predicate('bisected')
648 @predicate('bisected', safe=True)
634 def bisected(repo, subset, x):
649 def bisected(repo, subset, x):
635 return bisect(repo, subset, x)
650 return bisect(repo, subset, x)
636
651
637 @predicate('bookmark([name])')
652 @predicate('bookmark([name])', safe=True)
638 def bookmark(repo, subset, x):
653 def bookmark(repo, subset, x):
639 """The named bookmark or all bookmarks.
654 """The named bookmark or all bookmarks.
640
655
@@ -672,7 +687,7 b' def bookmark(repo, subset, x):'
672 bms -= set([node.nullrev])
687 bms -= set([node.nullrev])
673 return subset & bms
688 return subset & bms
674
689
675 @predicate('branch(string or set)')
690 @predicate('branch(string or set)', safe=True)
676 def branch(repo, subset, x):
691 def branch(repo, subset, x):
677 """
692 """
678 All changesets belonging to the given branch or the branches of the given
693 All changesets belonging to the given branch or the branches of the given
@@ -709,7 +724,7 b' def branch(repo, subset, x):'
709 c = s.__contains__
724 c = s.__contains__
710 return subset.filter(lambda r: c(r) or getbi(r)[0] in b)
725 return subset.filter(lambda r: c(r) or getbi(r)[0] in b)
711
726
712 @predicate('bumped()')
727 @predicate('bumped()', safe=True)
713 def bumped(repo, subset, x):
728 def bumped(repo, subset, x):
714 """Mutable changesets marked as successors of public changesets.
729 """Mutable changesets marked as successors of public changesets.
715
730
@@ -720,7 +735,7 b' def bumped(repo, subset, x):'
720 bumped = obsmod.getrevs(repo, 'bumped')
735 bumped = obsmod.getrevs(repo, 'bumped')
721 return subset & bumped
736 return subset & bumped
722
737
723 @predicate('bundle()')
738 @predicate('bundle()', safe=True)
724 def bundle(repo, subset, x):
739 def bundle(repo, subset, x):
725 """Changesets in the bundle.
740 """Changesets in the bundle.
726
741
@@ -780,7 +795,7 b' def _children(repo, narrow, parentset):'
780 # This does not break because of other fullreposet misbehavior.
795 # This does not break because of other fullreposet misbehavior.
781 return baseset(cs)
796 return baseset(cs)
782
797
783 @predicate('children(set)')
798 @predicate('children(set)', safe=True)
784 def children(repo, subset, x):
799 def children(repo, subset, x):
785 """Child changesets of changesets in set.
800 """Child changesets of changesets in set.
786 """
801 """
@@ -788,7 +803,7 b' def children(repo, subset, x):'
788 cs = _children(repo, subset, s)
803 cs = _children(repo, subset, s)
789 return subset & cs
804 return subset & cs
790
805
791 @predicate('closed()')
806 @predicate('closed()', safe=True)
792 def closed(repo, subset, x):
807 def closed(repo, subset, x):
793 """Changeset is closed.
808 """Changeset is closed.
794 """
809 """
@@ -823,7 +838,7 b' def contains(repo, subset, x):'
823
838
824 return subset.filter(matches)
839 return subset.filter(matches)
825
840
826 @predicate('converted([id])')
841 @predicate('converted([id])', safe=True)
827 def converted(repo, subset, x):
842 def converted(repo, subset, x):
828 """Changesets converted from the given identifier in the old repository if
843 """Changesets converted from the given identifier in the old repository if
829 present, or all converted changesets if no identifier is specified.
844 present, or all converted changesets if no identifier is specified.
@@ -845,7 +860,7 b' def converted(repo, subset, x):'
845
860
846 return subset.filter(lambda r: _matchvalue(r))
861 return subset.filter(lambda r: _matchvalue(r))
847
862
848 @predicate('date(interval)')
863 @predicate('date(interval)', safe=True)
849 def date(repo, subset, x):
864 def date(repo, subset, x):
850 """Changesets within the interval, see :hg:`help dates`.
865 """Changesets within the interval, see :hg:`help dates`.
851 """
866 """
@@ -854,7 +869,7 b' def date(repo, subset, x):'
854 dm = util.matchdate(ds)
869 dm = util.matchdate(ds)
855 return subset.filter(lambda x: dm(repo[x].date()[0]))
870 return subset.filter(lambda x: dm(repo[x].date()[0]))
856
871
857 @predicate('desc(string)')
872 @predicate('desc(string)', safe=True)
858 def desc(repo, subset, x):
873 def desc(repo, subset, x):
859 """Search commit message for string. The match is case-insensitive.
874 """Search commit message for string. The match is case-insensitive.
860 """
875 """
@@ -886,19 +901,19 b' def _descendants(repo, subset, x, follow'
886 result = subset & result
901 result = subset & result
887 return result
902 return result
888
903
889 @predicate('descendants(set)')
904 @predicate('descendants(set)', safe=True)
890 def descendants(repo, subset, x):
905 def descendants(repo, subset, x):
891 """Changesets which are descendants of changesets in set.
906 """Changesets which are descendants of changesets in set.
892 """
907 """
893 return _descendants(repo, subset, x)
908 return _descendants(repo, subset, x)
894
909
895 @predicate('_firstdescendants')
910 @predicate('_firstdescendants', safe=True)
896 def _firstdescendants(repo, subset, x):
911 def _firstdescendants(repo, subset, x):
897 # ``_firstdescendants(set)``
912 # ``_firstdescendants(set)``
898 # Like ``descendants(set)`` but follows only the first parents.
913 # Like ``descendants(set)`` but follows only the first parents.
899 return _descendants(repo, subset, x, followfirst=True)
914 return _descendants(repo, subset, x, followfirst=True)
900
915
901 @predicate('destination([set])')
916 @predicate('destination([set])', safe=True)
902 def destination(repo, subset, x):
917 def destination(repo, subset, x):
903 """Changesets that were created by a graft, transplant or rebase operation,
918 """Changesets that were created by a graft, transplant or rebase operation,
904 with the given revisions specified as the source. Omitting the optional set
919 with the given revisions specified as the source. Omitting the optional set
@@ -942,7 +957,7 b' def destination(repo, subset, x):'
942
957
943 return subset.filter(dests.__contains__)
958 return subset.filter(dests.__contains__)
944
959
945 @predicate('divergent()')
960 @predicate('divergent()', safe=True)
946 def divergent(repo, subset, x):
961 def divergent(repo, subset, x):
947 """
962 """
948 Final successors of changesets with an alternative set of final successors.
963 Final successors of changesets with an alternative set of final successors.
@@ -952,7 +967,7 b' def divergent(repo, subset, x):'
952 divergent = obsmod.getrevs(repo, 'divergent')
967 divergent = obsmod.getrevs(repo, 'divergent')
953 return subset & divergent
968 return subset & divergent
954
969
955 @predicate('extinct()')
970 @predicate('extinct()', safe=True)
956 def extinct(repo, subset, x):
971 def extinct(repo, subset, x):
957 """Obsolete changesets with obsolete descendants only.
972 """Obsolete changesets with obsolete descendants only.
958 """
973 """
@@ -961,7 +976,7 b' def extinct(repo, subset, x):'
961 extincts = obsmod.getrevs(repo, 'extinct')
976 extincts = obsmod.getrevs(repo, 'extinct')
962 return subset & extincts
977 return subset & extincts
963
978
964 @predicate('extra(label, [value])')
979 @predicate('extra(label, [value])', safe=True)
965 def extra(repo, subset, x):
980 def extra(repo, subset, x):
966 """Changesets with the given label in the extra metadata, with the given
981 """Changesets with the given label in the extra metadata, with the given
967 optional value.
982 optional value.
@@ -991,7 +1006,7 b' def extra(repo, subset, x):'
991
1006
992 return subset.filter(lambda r: _matchvalue(r))
1007 return subset.filter(lambda r: _matchvalue(r))
993
1008
994 @predicate('filelog(pattern)')
1009 @predicate('filelog(pattern)', safe=True)
995 def filelog(repo, subset, x):
1010 def filelog(repo, subset, x):
996 """Changesets connected to the specified filelog.
1011 """Changesets connected to the specified filelog.
997
1012
@@ -1106,7 +1121,7 b' def filelog(repo, subset, x):'
1106
1121
1107 return subset & s
1122 return subset & s
1108
1123
1109 @predicate('first(set, [n])')
1124 @predicate('first(set, [n])', safe=True)
1110 def first(repo, subset, x):
1125 def first(repo, subset, x):
1111 """An alias for limit().
1126 """An alias for limit().
1112 """
1127 """
@@ -1132,7 +1147,7 b' def _follow(repo, subset, x, name, follo'
1132
1147
1133 return subset & s
1148 return subset & s
1134
1149
1135 @predicate('follow([pattern])')
1150 @predicate('follow([pattern])', safe=True)
1136 def follow(repo, subset, x):
1151 def follow(repo, subset, x):
1137 """
1152 """
1138 An alias for ``::.`` (ancestors of the working directory's first parent).
1153 An alias for ``::.`` (ancestors of the working directory's first parent).
@@ -1141,14 +1156,14 b' def follow(repo, subset, x):'
1141 """
1156 """
1142 return _follow(repo, subset, x, 'follow')
1157 return _follow(repo, subset, x, 'follow')
1143
1158
1144 @predicate('_followfirst')
1159 @predicate('_followfirst', safe=True)
1145 def _followfirst(repo, subset, x):
1160 def _followfirst(repo, subset, x):
1146 # ``followfirst([pattern])``
1161 # ``followfirst([pattern])``
1147 # Like ``follow([pattern])`` but follows only the first parent of
1162 # Like ``follow([pattern])`` but follows only the first parent of
1148 # every revisions or files revisions.
1163 # every revisions or files revisions.
1149 return _follow(repo, subset, x, '_followfirst', followfirst=True)
1164 return _follow(repo, subset, x, '_followfirst', followfirst=True)
1150
1165
1151 @predicate('all()')
1166 @predicate('all()', safe=True)
1152 def getall(repo, subset, x):
1167 def getall(repo, subset, x):
1153 """All changesets, the same as ``0:tip``.
1168 """All changesets, the same as ``0:tip``.
1154 """
1169 """
@@ -1177,7 +1192,7 b' def grep(repo, subset, x):'
1177
1192
1178 return subset.filter(matches)
1193 return subset.filter(matches)
1179
1194
1180 @predicate('_matchfiles')
1195 @predicate('_matchfiles', safe=True)
1181 def _matchfiles(repo, subset, x):
1196 def _matchfiles(repo, subset, x):
1182 # _matchfiles takes a revset list of prefixed arguments:
1197 # _matchfiles takes a revset list of prefixed arguments:
1183 #
1198 #
@@ -1243,7 +1258,7 b' def _matchfiles(repo, subset, x):'
1243
1258
1244 return subset.filter(matches)
1259 return subset.filter(matches)
1245
1260
1246 @predicate('file(pattern)')
1261 @predicate('file(pattern)', safe=True)
1247 def hasfile(repo, subset, x):
1262 def hasfile(repo, subset, x):
1248 """Changesets affecting files matched by pattern.
1263 """Changesets affecting files matched by pattern.
1249
1264
@@ -1256,7 +1271,7 b' def hasfile(repo, subset, x):'
1256 pat = getstring(x, _("file requires a pattern"))
1271 pat = getstring(x, _("file requires a pattern"))
1257 return _matchfiles(repo, subset, ('string', 'p:' + pat))
1272 return _matchfiles(repo, subset, ('string', 'p:' + pat))
1258
1273
1259 @predicate('head()')
1274 @predicate('head()', safe=True)
1260 def head(repo, subset, x):
1275 def head(repo, subset, x):
1261 """Changeset is a named branch head.
1276 """Changeset is a named branch head.
1262 """
1277 """
@@ -1272,7 +1287,7 b' def head(repo, subset, x):'
1272 # necessary to ensure we preserve the order in subset.
1287 # necessary to ensure we preserve the order in subset.
1273 return baseset(hs) & subset
1288 return baseset(hs) & subset
1274
1289
1275 @predicate('heads(set)')
1290 @predicate('heads(set)', safe=True)
1276 def heads(repo, subset, x):
1291 def heads(repo, subset, x):
1277 """Members of set with no children in set.
1292 """Members of set with no children in set.
1278 """
1293 """
@@ -1280,7 +1295,7 b' def heads(repo, subset, x):'
1280 ps = parents(repo, subset, x)
1295 ps = parents(repo, subset, x)
1281 return s - ps
1296 return s - ps
1282
1297
1283 @predicate('hidden()')
1298 @predicate('hidden()', safe=True)
1284 def hidden(repo, subset, x):
1299 def hidden(repo, subset, x):
1285 """Hidden changesets.
1300 """Hidden changesets.
1286 """
1301 """
@@ -1289,7 +1304,7 b' def hidden(repo, subset, x):'
1289 hiddenrevs = repoview.filterrevs(repo, 'visible')
1304 hiddenrevs = repoview.filterrevs(repo, 'visible')
1290 return subset & hiddenrevs
1305 return subset & hiddenrevs
1291
1306
1292 @predicate('keyword(string)')
1307 @predicate('keyword(string)', safe=True)
1293 def keyword(repo, subset, x):
1308 def keyword(repo, subset, x):
1294 """Search commit message, user name, and names of changed files for
1309 """Search commit message, user name, and names of changed files for
1295 string. The match is case-insensitive.
1310 string. The match is case-insensitive.
@@ -1304,7 +1319,7 b' def keyword(repo, subset, x):'
1304
1319
1305 return subset.filter(matches)
1320 return subset.filter(matches)
1306
1321
1307 @predicate('limit(set[, n[, offset]])')
1322 @predicate('limit(set[, n[, offset]])', safe=True)
1308 def limit(repo, subset, x):
1323 def limit(repo, subset, x):
1309 """First n members of set, defaulting to 1, starting from offset.
1324 """First n members of set, defaulting to 1, starting from offset.
1310 """
1325 """
@@ -1340,7 +1355,7 b' def limit(repo, subset, x):'
1340 result.append(y)
1355 result.append(y)
1341 return baseset(result)
1356 return baseset(result)
1342
1357
1343 @predicate('last(set, [n])')
1358 @predicate('last(set, [n])', safe=True)
1344 def last(repo, subset, x):
1359 def last(repo, subset, x):
1345 """Last n members of set, defaulting to 1.
1360 """Last n members of set, defaulting to 1.
1346 """
1361 """
@@ -1366,7 +1381,7 b' def last(repo, subset, x):'
1366 result.append(y)
1381 result.append(y)
1367 return baseset(result)
1382 return baseset(result)
1368
1383
1369 @predicate('max(set)')
1384 @predicate('max(set)', safe=True)
1370 def maxrev(repo, subset, x):
1385 def maxrev(repo, subset, x):
1371 """Changeset with highest revision number in set.
1386 """Changeset with highest revision number in set.
1372 """
1387 """
@@ -1381,7 +1396,7 b' def maxrev(repo, subset, x):'
1381 pass
1396 pass
1382 return baseset()
1397 return baseset()
1383
1398
1384 @predicate('merge()')
1399 @predicate('merge()', safe=True)
1385 def merge(repo, subset, x):
1400 def merge(repo, subset, x):
1386 """Changeset is a merge changeset.
1401 """Changeset is a merge changeset.
1387 """
1402 """
@@ -1390,7 +1405,7 b' def merge(repo, subset, x):'
1390 cl = repo.changelog
1405 cl = repo.changelog
1391 return subset.filter(lambda r: cl.parentrevs(r)[1] != -1)
1406 return subset.filter(lambda r: cl.parentrevs(r)[1] != -1)
1392
1407
1393 @predicate('branchpoint()')
1408 @predicate('branchpoint()', safe=True)
1394 def branchpoint(repo, subset, x):
1409 def branchpoint(repo, subset, x):
1395 """Changesets with more than one child.
1410 """Changesets with more than one child.
1396 """
1411 """
@@ -1409,7 +1424,7 b' def branchpoint(repo, subset, x):'
1409 parentscount[p - baserev] += 1
1424 parentscount[p - baserev] += 1
1410 return subset.filter(lambda r: parentscount[r - baserev] > 1)
1425 return subset.filter(lambda r: parentscount[r - baserev] > 1)
1411
1426
1412 @predicate('min(set)')
1427 @predicate('min(set)', safe=True)
1413 def minrev(repo, subset, x):
1428 def minrev(repo, subset, x):
1414 """Changeset with lowest revision number in set.
1429 """Changeset with lowest revision number in set.
1415 """
1430 """
@@ -1424,7 +1439,7 b' def minrev(repo, subset, x):'
1424 pass
1439 pass
1425 return baseset()
1440 return baseset()
1426
1441
1427 @predicate('modifies(pattern)')
1442 @predicate('modifies(pattern)', safe=True)
1428 def modifies(repo, subset, x):
1443 def modifies(repo, subset, x):
1429 """Changesets modifying files matched by pattern.
1444 """Changesets modifying files matched by pattern.
1430
1445
@@ -1474,7 +1489,7 b' def named(repo, subset, x):'
1474 names -= set([node.nullrev])
1489 names -= set([node.nullrev])
1475 return subset & names
1490 return subset & names
1476
1491
1477 @predicate('id(string)')
1492 @predicate('id(string)', safe=True)
1478 def node_(repo, subset, x):
1493 def node_(repo, subset, x):
1479 """Revision non-ambiguously specified by the given hex string prefix.
1494 """Revision non-ambiguously specified by the given hex string prefix.
1480 """
1495 """
@@ -1498,7 +1513,7 b' def node_(repo, subset, x):'
1498 result = baseset([rn])
1513 result = baseset([rn])
1499 return result & subset
1514 return result & subset
1500
1515
1501 @predicate('obsolete()')
1516 @predicate('obsolete()', safe=True)
1502 def obsolete(repo, subset, x):
1517 def obsolete(repo, subset, x):
1503 """Mutable changeset with a newer version."""
1518 """Mutable changeset with a newer version."""
1504 # i18n: "obsolete" is a keyword
1519 # i18n: "obsolete" is a keyword
@@ -1506,7 +1521,7 b' def obsolete(repo, subset, x):'
1506 obsoletes = obsmod.getrevs(repo, 'obsolete')
1521 obsoletes = obsmod.getrevs(repo, 'obsolete')
1507 return subset & obsoletes
1522 return subset & obsoletes
1508
1523
1509 @predicate('only(set, [set])')
1524 @predicate('only(set, [set])', safe=True)
1510 def only(repo, subset, x):
1525 def only(repo, subset, x):
1511 """Changesets that are ancestors of the first set that are not ancestors
1526 """Changesets that are ancestors of the first set that are not ancestors
1512 of any other head in the repo. If a second set is specified, the result
1527 of any other head in the repo. If a second set is specified, the result
@@ -1532,7 +1547,7 b' def only(repo, subset, x):'
1532 # some optimisations from the fact this is a baseset.
1547 # some optimisations from the fact this is a baseset.
1533 return subset & results
1548 return subset & results
1534
1549
1535 @predicate('origin([set])')
1550 @predicate('origin([set])', safe=True)
1536 def origin(repo, subset, x):
1551 def origin(repo, subset, x):
1537 """
1552 """
1538 Changesets that were specified as a source for the grafts, transplants or
1553 Changesets that were specified as a source for the grafts, transplants or
@@ -1564,7 +1579,7 b' def origin(repo, subset, x):'
1564 # some optimisations from the fact this is a baseset.
1579 # some optimisations from the fact this is a baseset.
1565 return subset & o
1580 return subset & o
1566
1581
1567 @predicate('outgoing([path])')
1582 @predicate('outgoing([path])', safe=True)
1568 def outgoing(repo, subset, x):
1583 def outgoing(repo, subset, x):
1569 """Changesets not found in the specified destination repository, or the
1584 """Changesets not found in the specified destination repository, or the
1570 default push location.
1585 default push location.
@@ -1591,7 +1606,7 b' def outgoing(repo, subset, x):'
1591 o = set([cl.rev(r) for r in outgoing.missing])
1606 o = set([cl.rev(r) for r in outgoing.missing])
1592 return subset & o
1607 return subset & o
1593
1608
1594 @predicate('p1([set])')
1609 @predicate('p1([set])', safe=True)
1595 def p1(repo, subset, x):
1610 def p1(repo, subset, x):
1596 """First parent of changesets in set, or the working directory.
1611 """First parent of changesets in set, or the working directory.
1597 """
1612 """
@@ -1610,7 +1625,7 b' def p1(repo, subset, x):'
1610 # some optimisations from the fact this is a baseset.
1625 # some optimisations from the fact this is a baseset.
1611 return subset & ps
1626 return subset & ps
1612
1627
1613 @predicate('p2([set])')
1628 @predicate('p2([set])', safe=True)
1614 def p2(repo, subset, x):
1629 def p2(repo, subset, x):
1615 """Second parent of changesets in set, or the working directory.
1630 """Second parent of changesets in set, or the working directory.
1616 """
1631 """
@@ -1633,7 +1648,7 b' def p2(repo, subset, x):'
1633 # some optimisations from the fact this is a baseset.
1648 # some optimisations from the fact this is a baseset.
1634 return subset & ps
1649 return subset & ps
1635
1650
1636 @predicate('parents([set])')
1651 @predicate('parents([set])', safe=True)
1637 def parents(repo, subset, x):
1652 def parents(repo, subset, x):
1638 """
1653 """
1639 The set of all parents for all changesets in set, or the working directory.
1654 The set of all parents for all changesets in set, or the working directory.
@@ -1666,7 +1681,7 b' def _phase(repo, subset, target):'
1666 condition = lambda r: phase(repo, r) == target
1681 condition = lambda r: phase(repo, r) == target
1667 return subset.filter(condition, cache=False)
1682 return subset.filter(condition, cache=False)
1668
1683
1669 @predicate('draft()')
1684 @predicate('draft()', safe=True)
1670 def draft(repo, subset, x):
1685 def draft(repo, subset, x):
1671 """Changeset in draft phase."""
1686 """Changeset in draft phase."""
1672 # i18n: "draft" is a keyword
1687 # i18n: "draft" is a keyword
@@ -1674,7 +1689,7 b' def draft(repo, subset, x):'
1674 target = phases.draft
1689 target = phases.draft
1675 return _phase(repo, subset, target)
1690 return _phase(repo, subset, target)
1676
1691
1677 @predicate('secret()')
1692 @predicate('secret()', safe=True)
1678 def secret(repo, subset, x):
1693 def secret(repo, subset, x):
1679 """Changeset in secret phase."""
1694 """Changeset in secret phase."""
1680 # i18n: "secret" is a keyword
1695 # i18n: "secret" is a keyword
@@ -1707,7 +1722,7 b' def parentspec(repo, subset, x, n):'
1707 ps.add(parents[1])
1722 ps.add(parents[1])
1708 return subset & ps
1723 return subset & ps
1709
1724
1710 @predicate('present(set)')
1725 @predicate('present(set)', safe=True)
1711 def present(repo, subset, x):
1726 def present(repo, subset, x):
1712 """An empty set, if any revision in set isn't found; otherwise,
1727 """An empty set, if any revision in set isn't found; otherwise,
1713 all revisions in set.
1728 all revisions in set.
@@ -1722,7 +1737,7 b' def present(repo, subset, x):'
1722 return baseset()
1737 return baseset()
1723
1738
1724 # for internal use
1739 # for internal use
1725 @predicate('_notpublic')
1740 @predicate('_notpublic', safe=True)
1726 def _notpublic(repo, subset, x):
1741 def _notpublic(repo, subset, x):
1727 getargs(x, 0, 0, "_notpublic takes no arguments")
1742 getargs(x, 0, 0, "_notpublic takes no arguments")
1728 repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded
1743 repo._phasecache.loadphaserevs(repo) # ensure phase's sets are loaded
@@ -1739,7 +1754,7 b' def _notpublic(repo, subset, x):'
1739 condition = lambda r: phase(repo, r) != target
1754 condition = lambda r: phase(repo, r) != target
1740 return subset.filter(condition, cache=False)
1755 return subset.filter(condition, cache=False)
1741
1756
1742 @predicate('public()')
1757 @predicate('public()', safe=True)
1743 def public(repo, subset, x):
1758 def public(repo, subset, x):
1744 """Changeset in public phase."""
1759 """Changeset in public phase."""
1745 # i18n: "public" is a keyword
1760 # i18n: "public" is a keyword
@@ -1749,7 +1764,7 b' def public(repo, subset, x):'
1749 condition = lambda r: phase(repo, r) == target
1764 condition = lambda r: phase(repo, r) == target
1750 return subset.filter(condition, cache=False)
1765 return subset.filter(condition, cache=False)
1751
1766
1752 @predicate('remote([id [,path]])')
1767 @predicate('remote([id [,path]])', safe=True)
1753 def remote(repo, subset, x):
1768 def remote(repo, subset, x):
1754 """Local revision that corresponds to the given identifier in a
1769 """Local revision that corresponds to the given identifier in a
1755 remote repository, if present. Here, the '.' identifier is a
1770 remote repository, if present. Here, the '.' identifier is a
@@ -1784,7 +1799,7 b' def remote(repo, subset, x):'
1784 return baseset([r])
1799 return baseset([r])
1785 return baseset()
1800 return baseset()
1786
1801
1787 @predicate('removes(pattern)')
1802 @predicate('removes(pattern)', safe=True)
1788 def removes(repo, subset, x):
1803 def removes(repo, subset, x):
1789 """Changesets which remove files matching pattern.
1804 """Changesets which remove files matching pattern.
1790
1805
@@ -1796,7 +1811,7 b' def removes(repo, subset, x):'
1796 pat = getstring(x, _("removes requires a pattern"))
1811 pat = getstring(x, _("removes requires a pattern"))
1797 return checkstatus(repo, subset, pat, 2)
1812 return checkstatus(repo, subset, pat, 2)
1798
1813
1799 @predicate('rev(number)')
1814 @predicate('rev(number)', safe=True)
1800 def rev(repo, subset, x):
1815 def rev(repo, subset, x):
1801 """Revision with the given numeric identifier.
1816 """Revision with the given numeric identifier.
1802 """
1817 """
@@ -1812,7 +1827,7 b' def rev(repo, subset, x):'
1812 return baseset()
1827 return baseset()
1813 return subset & baseset([l])
1828 return subset & baseset([l])
1814
1829
1815 @predicate('matching(revision [, field])')
1830 @predicate('matching(revision [, field])', safe=True)
1816 def matching(repo, subset, x):
1831 def matching(repo, subset, x):
1817 """Changesets in which a given set of fields match the set of fields in the
1832 """Changesets in which a given set of fields match the set of fields in the
1818 selected revision or set.
1833 selected revision or set.
@@ -1924,7 +1939,7 b' def matching(repo, subset, x):'
1924
1939
1925 return subset.filter(matches)
1940 return subset.filter(matches)
1926
1941
1927 @predicate('reverse(set)')
1942 @predicate('reverse(set)', safe=True)
1928 def reverse(repo, subset, x):
1943 def reverse(repo, subset, x):
1929 """Reverse order of set.
1944 """Reverse order of set.
1930 """
1945 """
@@ -1932,7 +1947,7 b' def reverse(repo, subset, x):'
1932 l.reverse()
1947 l.reverse()
1933 return l
1948 return l
1934
1949
1935 @predicate('roots(set)')
1950 @predicate('roots(set)', safe=True)
1936 def roots(repo, subset, x):
1951 def roots(repo, subset, x):
1937 """Changesets in set with no parent changeset in set.
1952 """Changesets in set with no parent changeset in set.
1938 """
1953 """
@@ -1945,7 +1960,7 b' def roots(repo, subset, x):'
1945 return True
1960 return True
1946 return subset & s.filter(filter)
1961 return subset & s.filter(filter)
1947
1962
1948 @predicate('sort(set[, [-]key...])')
1963 @predicate('sort(set[, [-]key...])', safe=True)
1949 def sort(repo, subset, x):
1964 def sort(repo, subset, x):
1950 """Sort set by keys. The default sort order is ascending, specify a key
1965 """Sort set by keys. The default sort order is ascending, specify a key
1951 as ``-key`` to sort in descending order.
1966 as ``-key`` to sort in descending order.
@@ -2057,7 +2072,7 b' def _substringmatcher(pattern):'
2057 matcher = lambda s: pattern in s
2072 matcher = lambda s: pattern in s
2058 return kind, pattern, matcher
2073 return kind, pattern, matcher
2059
2074
2060 @predicate('tag([name])')
2075 @predicate('tag([name])', safe=True)
2061 def tag(repo, subset, x):
2076 def tag(repo, subset, x):
2062 """The specified tag by name, or all tagged revisions if no name is given.
2077 """The specified tag by name, or all tagged revisions if no name is given.
2063
2078
@@ -2086,11 +2101,11 b' def tag(repo, subset, x):'
2086 s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
2101 s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
2087 return subset & s
2102 return subset & s
2088
2103
2089 @predicate('tagged')
2104 @predicate('tagged', safe=True)
2090 def tagged(repo, subset, x):
2105 def tagged(repo, subset, x):
2091 return tag(repo, subset, x)
2106 return tag(repo, subset, x)
2092
2107
2093 @predicate('unstable()')
2108 @predicate('unstable()', safe=True)
2094 def unstable(repo, subset, x):
2109 def unstable(repo, subset, x):
2095 """Non-obsolete changesets with obsolete ancestors.
2110 """Non-obsolete changesets with obsolete ancestors.
2096 """
2111 """
@@ -2100,7 +2115,7 b' def unstable(repo, subset, x):'
2100 return subset & unstables
2115 return subset & unstables
2101
2116
2102
2117
2103 @predicate('user(string)')
2118 @predicate('user(string)', safe=True)
2104 def user(repo, subset, x):
2119 def user(repo, subset, x):
2105 """User name contains string. The match is case-insensitive.
2120 """User name contains string. The match is case-insensitive.
2106
2121
@@ -2111,7 +2126,7 b' def user(repo, subset, x):'
2111 return author(repo, subset, x)
2126 return author(repo, subset, x)
2112
2127
2113 # experimental
2128 # experimental
2114 @predicate('wdir')
2129 @predicate('wdir', safe=True)
2115 def wdir(repo, subset, x):
2130 def wdir(repo, subset, x):
2116 # i18n: "wdir" is a keyword
2131 # i18n: "wdir" is a keyword
2117 getargs(x, 0, 0, _("wdir takes no arguments"))
2132 getargs(x, 0, 0, _("wdir takes no arguments"))
@@ -2120,7 +2135,7 b' def wdir(repo, subset, x):'
2120 return baseset()
2135 return baseset()
2121
2136
2122 # for internal use
2137 # for internal use
2123 @predicate('_list')
2138 @predicate('_list', safe=True)
2124 def _list(repo, subset, x):
2139 def _list(repo, subset, x):
2125 s = getstring(x, "internal error")
2140 s = getstring(x, "internal error")
2126 if not s:
2141 if not s:
@@ -2150,7 +2165,7 b' def _list(repo, subset, x):'
2150 return baseset(ls)
2165 return baseset(ls)
2151
2166
2152 # for internal use
2167 # for internal use
2153 @predicate('_intlist')
2168 @predicate('_intlist', safe=True)
2154 def _intlist(repo, subset, x):
2169 def _intlist(repo, subset, x):
2155 s = getstring(x, "internal error")
2170 s = getstring(x, "internal error")
2156 if not s:
2171 if not s:
@@ -2160,7 +2175,7 b' def _intlist(repo, subset, x):'
2160 return baseset([r for r in ls if r in s])
2175 return baseset([r for r in ls if r in s])
2161
2176
2162 # for internal use
2177 # for internal use
2163 @predicate('_hexlist')
2178 @predicate('_hexlist', safe=True)
2164 def _hexlist(repo, subset, x):
2179 def _hexlist(repo, subset, x):
2165 s = getstring(x, "internal error")
2180 s = getstring(x, "internal error")
2166 if not s:
2181 if not s:
@@ -2170,80 +2185,6 b' def _hexlist(repo, subset, x):'
2170 s = subset
2185 s = subset
2171 return baseset([r for r in ls if r in s])
2186 return baseset([r for r in ls if r in s])
2172
2187
2173 # symbols which can't be used for a DoS attack for any given input
2174 # (e.g. those which accept regexes as plain strings shouldn't be included)
2175 # functions that just return a lot of changesets (like all) don't count here
2176 safesymbols = set([
2177 "adds",
2178 "all",
2179 "ancestor",
2180 "ancestors",
2181 "_firstancestors",
2182 "author",
2183 "bisect",
2184 "bisected",
2185 "bookmark",
2186 "branch",
2187 "branchpoint",
2188 "bumped",
2189 "bundle",
2190 "children",
2191 "closed",
2192 "converted",
2193 "date",
2194 "desc",
2195 "descendants",
2196 "_firstdescendants",
2197 "destination",
2198 "divergent",
2199 "draft",
2200 "extinct",
2201 "extra",
2202 "file",
2203 "filelog",
2204 "first",
2205 "follow",
2206 "_followfirst",
2207 "head",
2208 "heads",
2209 "hidden",
2210 "id",
2211 "keyword",
2212 "last",
2213 "limit",
2214 "_matchfiles",
2215 "max",
2216 "merge",
2217 "min",
2218 "modifies",
2219 "obsolete",
2220 "only",
2221 "origin",
2222 "outgoing",
2223 "p1",
2224 "p2",
2225 "parents",
2226 "present",
2227 "public",
2228 "_notpublic",
2229 "remote",
2230 "removes",
2231 "rev",
2232 "reverse",
2233 "roots",
2234 "sort",
2235 "secret",
2236 "matching",
2237 "tag",
2238 "tagged",
2239 "user",
2240 "unstable",
2241 "wdir",
2242 "_list",
2243 "_intlist",
2244 "_hexlist",
2245 ])
2246
2247 methods = {
2188 methods = {
2248 "range": rangeset,
2189 "range": rangeset,
2249 "dagrange": dagrange,
2190 "dagrange": dagrange,
General Comments 0
You need to be logged in to leave comments. Login now