By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,844 Members | 836 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,844 IT Pros & Developers. It's quick & easy.

os.path.vnormpath

P: n/a
Written to normalize web server path names based on a virtual root. I
propose that something equivalent to this be added to os.path
-------------------------------------
import os.path
import copy

def vnormpath(root,path):
"""
Normalize a path based on a virtual root.
"""
r = copy.deepcopy(root)
p = copy.deepcopy(path)

if os.path.isabs(path):
return root + path
while os.path.commonprefix([root, os.path.normpath(os.path.join(r,p))])
<> root:
r = os.path.join(r,"junk")
return os.path.normpath(os.path.join(r,p))
if __name__ == "__main__":
print vnormpath("C:\\foo\\baz",
"..\\..\\..\\..\\foo\\baz\\..\\..\\..\\frob\\glop" )
Jul 18 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Ben Allfree wrote:
Written to normalize web server path names based on a virtual root. I
propose that something equivalent to this be added to os.path
The purpose remains unclear to me. Maybe you could expand a little.
For now, I suppose you intend vnormpath() to always return subfolders of
root.
-------------------------------------
import os.path
import copy

def vnormpath(root,path):
"""
Normalize a path based on a virtual root.
"""
r = copy.deepcopy(root)
p = copy.deepcopy(path)
Strings are "immutable", i. e. you can't change them once created. You
therefore need not (I'd rather say must not) copy them.

if os.path.isabs(path):
return root + path
This can give you funny paths on Windows like "C:/firstC:/second"; on Unix
you can get anywhere the supplier of *path* wants,
e. g. vnormpath("/home/peter", "/../ben") returns "/home/peter/../ben" which
is equivalent to "home/ben".
while os.path.commonprefix([root,
os.path.normpath(os.path.join(r,p))])
<> root:
r = os.path.join(r,"junk")
return os.path.normpath(os.path.join(r,p))
I tried to break that, too, but must admit I didn't succed so far :-)
By the way, most pythonistas favour != over <>.
if __name__ == "__main__":
print vnormpath("C:\\foo\\baz",
"..\\..\\..\\..\\foo\\baz\\..\\..\\..\\frob\\glop" )


The above demo is probably a good start, but try to think of a few more
use/test cases. For example, should
vnormpath("/home/ben", "/home/ben/temp") return "/home/ben/home/ben/temp" or
rather "home/ben/temp"? Also, I would compare vnormpath()'s actual against
the expected result instead of just printing it out. For production quality
code, have a look at the unittest module.

Conclusion: For the moment, be satisfied if you can fix the bugs and your
function serves *your* needs well. If you want to share the results, put it
on a web site.
For your code to make it into the python library, you have to convince
people that *they* need it badly and I dare say that you may face some
strong opposition.

Peter
Jul 18 '05 #2

P: n/a
Correct. vnormpath() should enforce the same rules web servers resolves a
virtual paths on the server side.

Example:

Virtual root - C:\foo\baz\wwwroot
URL - <a href="..\grop.html">

The above should never resolve to anything higher than
C:\foo\baz\wwwroot\grop.html regardless of its position in the web root
directory.

vnormpath("C:\\foo\\baz\\wwwroot", "..\\grop.html") ==
"C:\\foo\\baz\\wwwroot\\grop.html"

Likewise (here's a catch):

Virtual root - C:\foo\baz\wwwroot
URL - <a href="\..\..\baz\wwwroot\grop.html">

Should resolve to C:\foo\baz\wwwroot\baz\wwwroot\grop.html

I hope that make sense. My code is a start at solving the issue.

"Peter Otten" <__*******@web.de> wrote in message
news:bo*************@news.t-online.com...
Ben Allfree wrote:
Written to normalize web server path names based on a virtual root. I
propose that something equivalent to this be added to os.path
The purpose remains unclear to me. Maybe you could expand a little.
For now, I suppose you intend vnormpath() to always return subfolders of
root.
-------------------------------------
import os.path
import copy

def vnormpath(root,path):
"""
Normalize a path based on a virtual root.
"""
r = copy.deepcopy(root)
p = copy.deepcopy(path)


Strings are "immutable", i. e. you can't change them once created. You
therefore need not (I'd rather say must not) copy them.

if os.path.isabs(path):
return root + path


This can give you funny paths on Windows like "C:/firstC:/second"; on Unix
you can get anywhere the supplier of *path* wants,
e. g. vnormpath("/home/peter", "/../ben") returns "/home/peter/../ben"

which is equivalent to "home/ben".
while os.path.commonprefix([root,
os.path.normpath(os.path.join(r,p))])
<> root:
r = os.path.join(r,"junk")
return os.path.normpath(os.path.join(r,p))
I tried to break that, too, but must admit I didn't succed so far :-)
By the way, most pythonistas favour != over <>.
if __name__ == "__main__":
print vnormpath("C:\\foo\\baz",
"..\\..\\..\\..\\foo\\baz\\..\\..\\..\\frob\\glop" )


The above demo is probably a good start, but try to think of a few more
use/test cases. For example, should
vnormpath("/home/ben", "/home/ben/temp") return "/home/ben/home/ben/temp"

or rather "home/ben/temp"? Also, I would compare vnormpath()'s actual against
the expected result instead of just printing it out. For production quality code, have a look at the unittest module.

Conclusion: For the moment, be satisfied if you can fix the bugs and your
function serves *your* needs well. If you want to share the results, put it on a web site.
For your code to make it into the python library, you have to convince
people that *they* need it badly and I dare say that you may face some
strong opposition.

Peter

Jul 18 '05 #3

P: n/a
"Ben Allfree" <be****@bldigital.com> schreef:
Virtual root - C:\foo\baz\wwwroot
URL - <a href="\..\..\baz\wwwroot\grop.html">

Should resolve to C:\foo\baz\wwwroot\baz\wwwroot\grop.html


According to RFC-2396 this should resolve to:

C:\foo\baz\wwwroot\..\..\baz\wwwroot\grop.html

The ".." above are real path segments/directory names and don't have the
special "go up 1 level" meaning.

IMHO for web servers that map URL path segments to local paths this should
result in an HTTP error (when ".." is not allowed on the local filesystem).

They also mention that in practice your solution is in use by some parsers,
so people might not be too surprised by its functioning... ;-)
<http://www.cs.tut.fi/~jkorpela/rfc/2396/full.html#C>

--
JanC

"Be strict when sending and tolerant when receiving."
RFC 1958 - Architectural Principles of the Internet - section 3.9
Jul 18 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.