a +bAw@sddlZddlZddlZddlmZddlmZmZddl m Z m Z mZm Z ddl m Z ejrjddlmZe jZd d ZGd d d eZd dZddZddZddZddZddZdBddZddZddZdd ZdCd!d"ZdDd$d%Z dEd&d'Z!dFd(d)Z"Gd*d+d+e#Z$iZ%d,d-Z&e&d.d/d0d1Z'e&d2d2d3d4Z(hd5Z)e&d6d7d8d9Z*e&d:d;dd?Z,Gd@dAdAeZ-dS)GN)_)getattrsetattr)encodingerrorpycompat urllibcompat) stringutil)UnioncCs\z t|WStyYn0ztt|WStjyVttd|Yn0dS)zReturn the port for a given network service. If port is an integer, it's returned as is. If it's a string, it's looked up using socket.getservbyname(). If there's no matching service, error.Abort is raised. s+no port number associated with service '%s'N) int ValueErrorsocketZ getservbynamerZsysstrrAbortr)portr=/usr/lib64/python3.9/site-packages/mercurial/utils/urlutil.pygetport$s   rc@sveZdZdZdZdZedjZ dddZ dd Z e j d d Zd d Ze eZddZddZddZddZdS)urla Reliable URL parser. This parses URLs and provides attributes for the following components: ://:@:/?# Missing components are set to None. The only exception is fragment, which is set to '' if present but empty. If parsefragment is False, fragment is included in query. If parsequery is False, query is included in path. If both are False, both fragment and query are included in path. See http://www.ietf.org/rfc/rfc2396.txt for more information. Note that for backward compatibility reasons, bundle URLs do not take host names. That means 'bundle://../' has a path of '../'. Examples: >>> url(b'http://www.ietf.org/rfc/rfc2396.txt') >>> url(b'ssh://[::1]:2200//home/joe/repo') >>> url(b'file:///home/joe/repo') >>> url(b'file:///c:/temp/foo/') >>> url(b'bundle:foo') >>> url(b'bundle://../foo') >>> url(br'c:\foo\bar') >>> url(br'\\blah\blah\blah') >>> url(br'\\blah\blah\blah#baz') >>> url(br'file:///C:\users\me') Authentication credentials: >>> url(b'ssh://joe:xyz@x/repo') >>> url(b'ssh://joe@x/repo') Query strings and fragments: >>> url(b'http://host/a?b#c') >>> url(b'http://host/a?b#c', parsequery=False, parsefragment=False) Empty path: >>> url(b'') >>> url(b'#a') >>> url(b'http://host/') >>> url(b'http://host/#a') Only scheme: >>> url(b'http:') s!~*'()+s /!~*'()+:\s^[a-zA-Z0-9+.\-]+:TcCsd|_|_|_|_d|_|_|_|_d|_d|_ ||_ |r`d|vr`| dd\}|_t |sr| dr|||_dS| drd|_|dd}| d r|d d}||_dS||r| d d}|d r|\|_}d |_|sd}|jrd|_dSn|jr||_dS|rRd|vrR| dd\}|_|sDd}|jsRd|_|r| d r|d d dd}t|dkr|\|_}n|d |_d}|jsd|_|rt |sd|}|jr d|jvr |jdd\|_|_d |jvr|j d d\|_|_|js d|_|jr|d |jvr||j drP|jds||j|_ |jd d\|_|_|js|d|_|jr|jdkr|jdvrttd||_dD],}t||}|durt||t|qdS)NT#r \\bundle:bundle//r:rF?/@[]file)s localhosts 127.0.0.1s[::1]s(file:// URLs can only refer to localhost)userpasswdhostportpathfragment)schemeuserpasswdhostrpathqueryfragment _localpath _hostport _origpathsplithasdriveletter startswith _matchschemelenrsplitendswithrrrrrurlrequnquote)selfr. parsequery parsefragmentpartsavrrr__init__s               z url.__init__cCsdtd}|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j |_ |j |_ |S)Nstemporary useless value) rr.r*r+r,r-r/r0r1r2r3)r=urrrcopyszurl.copycCsFg}dD].}t||}|dur|d|t|fqdd|S)N)sschemer$r%r&r'r(squeryr)s%s: %rss, )rappendrbytestrjoin)r=attrsrArBrrr__repr__s  z url.__repr__cCs|jr6|j}|jdkrd|}|jr2|d|j7}|S|jd}|jsR|jsR|jr\|d7}n<|jr|jr~|jds~t|jr|d7}t|jr|d7}|jr|t j |j|j d7}|jr|dt j |j|j d7}|js|jr|d7}|jr(|jd r |j d s|t |j7}n ||j7}|j rD|dt |j 7}|jrT|d7}|jrr|t j |j|jd7}|jr|d |j7}|jd ur|dt j |j|jd7}|S) aJoin the URL's components back into a URL string. Examples: >>> bytes(url(b'http://user:pw@host:80/c:/bob?fo:oo#ba:ar')) 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar' >>> bytes(url(b'http://user:pw@host:80/?foo=bar&baz=42')) 'http://user:pw@host:80/?foo=bar&baz=42' >>> bytes(url(b'http://user:pw@host:80/?foo=bar%3dbaz')) 'http://user:pw@host:80/?foo=bar%3dbaz' >>> bytes(url(b'ssh://user:pw@[::1]:2200//home/joe#')) 'ssh://user:pw@[::1]:2200//home/joe#' >>> bytes(url(b'http://localhost:80//')) 'http://localhost:80//' >>> bytes(url(b'http://localhost:80/')) 'http://localhost:80/' >>> bytes(url(b'http://localhost:80')) 'http://localhost:80/' >>> bytes(url(b'bundle:foo')) 'bundle:foo' >>> bytes(url(b'bundle://../foo')) 'bundle:../foo' >>> bytes(url(b'path')) 'path' >>> bytes(url(b'file:///tmp/foo/bar')) 'file:///tmp/foo/bar' >>> bytes(url(b'file:///c:/tmp/foo/bar')) 'file:///c:/tmp/foo/bar' >>> print(url(br'bundle:foo\bar')) bundle:foo\bar >>> print(url(br'file:///D:\data\hg')) file:///D:\data\hg rrrrrr)safer r!r"rN)r1r.r*r0r+r,r-r6r5r;quote _safecharsr:r _safepcharsr/)r=srrr __bytes__sR"        z url.__bytes__c Csr|j|j}}z&d\|_|_t|}W|||_|_n|||_|_0|jsT|dfS|d||jf|j|jpldffS)N)NNr)r+r,bytesr-)r=r+r,rOrrrauthinfo`s   z url.authinfocCsF|jr|jdkrdSt|jr"dS|jdr2dS|jdrBdSdS)Nr#TrrF)r*r5r.r6r=rrrisabsos   z url.isabscCsd|jdks|jdkr^|jpd}t|jr:|jd|j}n |jdurZ|jrZt|sZd|}|S|jS)Nr#rr)r*r.r5r2r-r3r=r.rrr localpathzs  z url.localpathcCs|j p|jdkp|jdkS)z?whether localpath will return something that posixfile can openr#r)r*rSrrrislocals z url.islocalN)TT)__name__ __module__ __qualname____doc__rMrNremodcompilematchr7rCrErZ strmethodrJrP__str__rRrTrVrWrrrrr9sI  f P  rcCstt|jSN)boolrr*r.rrr hasschemesrccCs(t|o&|dddko&|ddS)Nr rrr)raisalpharbrrrr5sr5cCst|dddS)NF)r>r?)rrVrbrrr urllocalpathsrecCs<t|}|ds|dr8ttdt|fdS)a\check if a path / url is a potentially unsafe ssh exploit (SEC) This is a sanity check for ssh urls. ssh will parse the first item as an option; e.g. ssh://-oProxyCommand=curl${IFS}bad.server|sh/path. Let's prevent these potentially exploited urls entirely and warn the user. Raises an error.Abort when the url is unsafe. sssh://-s svn+ssh://-spotentially unsafe url: %rN)r;r<r6rrrrrGrbrrr checksafesshs rfcCst|}|jrd|_t|S)z$hide user credential in a url strings***)rr,rQrDrrr hidepasswordsrhcCst|}d|_|_t|S)z7remove all authentication information from a url stringN)rr+r,rQrgrrr removeauths ricCsfg}|dur@tt|jD] \}}|D]}|||fq(qn"|j|gD]}|||fqN|S)z+list all the (name, paths) in the passed uiN)sortedr iteritemspathsrFget)uiZ target_pathresultnamerlpr.rrr list_pathssrrcCs*zt|d|dWSty$YdS0dS)zLtry to build a path from a url Return None if no Path could built. Nrawloc)r.r)rnrrrrtry_paths ruccs|s`d|jvr&|jdD] }|Vqqd|jvrH|jdD] }|Vq:qtjtdtddn^|D]X}||jvr|j|D] }|Vq|qdt||}|durtd}||;}t||VqddS)z=yields all the `path` selected as push destination by `dests`s default-pushdefaults"default repository not configured!ssee 'hg help config.paths')hintNrepository %s does not exist)rlrZ ConfigErrorrru RepoError)reporndestsrqdestr.msgrrrget_push_pathss*        r~ccsP|s dg}|D]<}||jvr4|j|D] }|Vq&qt|d|dd}|VqdS)zDyields all the `(path, branch)` selected as pull source by `sources`rvNF) validate_path)rlr.)rzrnZsourcessourcerqrrrget_pull_pathss  rcCs~|durg}n|g}tt|||}t|dkrv|durRtd}|t||f;}ntd}|t|||f;}t||dS)a5return a unique `path` or abort if multiple are found This is useful for command and action that does not support multiple destination (yet). Note that for now, we cannot get multiple destination so this function is "trivial". The `action` parameter will be used for the error message. Nr 9default path points to %d urls while %s only supports one5path points to %d urls while %s only supports one: %sr)listr~r8rrr)actionrzrnr|r{r}rrrget_unique_push_paths   rrcCsg}|dur>d|jvr2|dd|jdDq|dnP||jvrd|dd|j|Dn*t||}|dur||jn ||t|dkr|durtd}|t||f;}ntd}|t|||f;}t|t |d |S) a?return a unique `(path, branch)` or abort if multiple are found This is useful for command and action that does not support multiple destination (yet). Note that for now, we cannot get multiple destination so this function is "trivial". The `action` parameter will be used for the error message. Nrvcss|] }|jVqdSr`rs.0rqrrr 0rz'get_unique_pull_path..css|] }|jVqdSr`rsrrrrr7rr rrr rlextendrFrurtr8rrrparseurl)rrzrnrdefault_branchesurlsr.r}rrrget_unique_pull_path#s*        rc Csg}|dur>d|jvr2|dd|jdDq|dnP||jvrd|dd|j|Dn*t||}|dur||jn ||t|dkr|durtd}|t|;}ntd}|t||f;}t||d }t ||\}}|||fS) z@return the `(origsource, path, branch)` selected as clone sourceNrvcss|] }|jVqdSr`rsrrrrrQrz!get_clone_path..css|] }|jVqdSr`rsrrrrrXrr s:default path points to %d urls while only one is supporteds6path points to %d urls while only one is supported: %srr) rnrrrr.r}rZ clone_pathbranchrrrget_clone_pathLs.       rcCs2t|}d}|jr|j}d|_t|||p,gffS)z5parse url#branch, returning (url, (branch, branches))N)rr0rQ)r.ZbranchesrDrrrrros rc@s"eZdZdZddZdddZdS)rlzRepresents a collection of paths and their configs. Data is initially derived from ui instances and the config files they have loaded. cCsNt|tjd}|jdddD]\}}|s2q$|d|\}}|d|}|||f}|j ||} | d} | durt | rt |} n|g} g} | D]`} tj | } tj| } t| stj| stjtj| | } t||| |d}| |q| ||<q$t|D]4\}}g}|D]}|t|||q$|||<qdS)N~pathsT)Z ignoresub multi-urls)rt suboptions)dictrCosr. expanduserZ configitemsconfigsuboptionsZ configsourceZ _path_to_rootrmr parseboolZ parselist expandvarsrcrTnormpathrHrFrjitemsr _chain_path)r=rnZ home_pathrpvalue_valuesub_optsrOZroot_keyrootZ multi_urlZ base_locsrllocrqZ old_paths new_pathsrrrrCs6          zpaths.__init__Nc Csd}||d|durn|s"d}nt|ttfs6|f}|D].}z||dWStyfYq:Yq:0q:dS|svdS||vr||dSt||}|durttd||j SdS)a Return a ``path`` from a string, falling back to default. ``name`` can be a named path or locations. Locations are filesystem paths or URIs. Returns None if ``name`` is not a registered path, a URI, or a local path to a repo. s9getpath is deprecated, use `get_*` functions from urlutils6.0Nrrrx) Z deprecwarn isinstancetuplerKeyErrorrurryrrt)r=rnrpdefaultr}kr.rrrgetpaths*      z paths.getpath)N)rXrYrZr[rCrrrrrrlys$rlcsfdd}|S)aDecorator used to declare a path sub-option. Arguments are the sub-option name and the attribute it should set on ``path`` instances. The decorated function will receive as arguments a ``ui`` instance, ``path`` instance, and the string value of this option from the config. The function should return the value that will be set on the ``path`` instance. This decorator can be used to perform additional verification of sub-options and to change the type of sub-options. cs|ft<|Sr`)_pathsuboptions)funcattroptionrrregisters zpathsuboption..registerr)rrrrrr pathsuboptionsrspushurlspushloccCsZt|}|js2td}||j|f;}||dS|jrR|td|jd|_t|S)Ns-(paths.%s:pushurl not a URL; ignoring: "%s") s:("#fragment" in paths.%s:pushurl not supported; ignoring) )rr*rrpwarnr0rQ)rnr.rrDr}rrrpushurlpathoptions  rspushrevcCs|Sr`r)rnr.rrrrpushrevpathoptionsr>smirrorrvsignoresbookmarks.modesbookmarks_modecCsH|tvr8|j}|durd}td}|||f;}|||dkrDd}|S)N*s2(paths.%s:bookmarks.mode has unknown value: "%s") rv)SUPPORTED_BOOKMARKS_MODESrprr)rnr.r path_namer}rrrbookmarks_mode_options  rrs multi_urlscCs.t|}|dur*|td|jd}|S)Ns.(paths.%s:multi-urls not a boolean; ignoring) F)r rrrrp)rnr.rresrrrmultiurls_pathoptions  rc Csg}|jjdkr||n||jj}|durVtd}||j|jjf;}t||D]}| }|j jdkrtd}||j|jjf;}t||j|_|j|_|j |_ |j dur|j |_ n"|j ddd}d||j f|_|j } | |j||| ||qZ|S) z\}\}}||vr,t||dq |||||}t|||q dSr`)rrkrr)r=rnZ sub_optionsZ suboptionrrrrrrrs  zpath._apply_suboptionsc Cs6ztjtj|dWSttfy0YdS0dS)zReturns True if the given path is a potentially valid repository. This is its own function so that extensions can change the definition of 'valid' in this case (like when pulling from a git repo into a hg one).s.hgFN)rr.isdirrH TypeErrorrrUrrrrszpath._isvalidlocalpathcCs:i}ttD]&\}\}}t||}|dur|||<q|S)z{Return sub-options and their values for this path. This is intended to be used for presentation purposes. N)rrkrr)r=dZsuboptrZ_funcrrrrrs   zpath.suboptions)NNNNT) rXrYrZr[rCrErrrpropertyrrrrrr.Cs 9    r.)N)N)Nr)r)N).rrer\rZi18nrrrrrrr r TYPE_CHECKINGtypingr r;robjectrrcr5rerfrhrirrrur~rrrrrrrlrrrrrrrrr.rrrrsR   [     ) # Q    !