fork download
  1. import re
  2.  
  3. test_paths = [
  4. 'a/b/c/../../x',
  5. 'a/b/c/../../x/..',
  6. 'a/b/c/../../../x',
  7. 'a/b/c/../../../../x',
  8. 'a/b/c/../../../../x/',
  9. 'a/b/c/../../../../x///',
  10. 'a/b/c/../../q/a/b/c/../../../../../x',
  11. '//a/b/c/../../q/a/././b/./c/../../..////../../../../../x',
  12. ]
  13.  
  14. for path in test_paths:
  15. print "INPUT: ", path
  16. path = '/' + path # secure from missing root
  17. path = re.sub(r'/+', '/', path) # remove any slash repetitions
  18. path = re.sub(r'(?<!\.)\.(?:/|$)', '', path) # remove any "./"
  19. while True: # remove any "dir/../"
  20. pp = re.sub(r'\w+\/\.\.(?:/|$)', '', path)
  21. if pp == path: # NB: we have to do this in a
  22. break # loop until path remains unchanged
  23. else: # to cope with input like this:
  24. path = pp # '/a/b/../c/../../d'
  25. path = re.sub(r'\.\.(?:/|$)', '', path) # remove oustanding '../' (cf. '/a/../../b')
  26. path = re.sub(r'/$', '', path) # remove trailing slash
  27. print "CANONICAL: ", path
Success #stdin #stdout 0s 23352KB
stdin
Standard input is empty
stdout
INPUT:  a/b/c/../../x
CANONICAL:  /a/x
INPUT:  a/b/c/../../x/..
CANONICAL:  /a
INPUT:  a/b/c/../../../x
CANONICAL:  /x
INPUT:  a/b/c/../../../../x
CANONICAL:  /x
INPUT:  a/b/c/../../../../x/
CANONICAL:  /x
INPUT:  a/b/c/../../../../x///
CANONICAL:  /x
INPUT:  a/b/c/../../q/a/b/c/../../../../../x
CANONICAL:  /x
INPUT:  //a/b/c/../../q/a/././b/./c/../../..////../../../../../x
CANONICAL:  /x