def secureFilePathresolve(self, uri, base=None): if base: uri = self.normalize(uri, base) path = Uri.UriToOsPath(uri) for prefix in self.path: if os.path.abspath(path).startswith(os.path.abspath(prefix)): if fileCache:#todo: this only works if secure file access is on return StringIO.StringIO(fileCache.getValue(path)) else: return SiteUriResolver._resolveFile(path) raise UriException(UriException.RESOURCE_ERROR, uri, 'Unauthorized')
def FileExists(context, uri): path = StringValue(uri) if path.startswith('file:'): path = Uri.UriToOsPath(path) #todo: security hole return Xbool(os.path.exists(path)) else: if path.startswith('path:'): path = path[len('path:'):] for prefix in InputSource.DefaultFactory.resolver.path: if os.path.exists(os.path.join(prefix.strip(), path)): return XTrue return XFalse
def _orig_resolve(self, uri, baseUri=None): """ This function takes a URI or a URI reference plus a base URI, produces a normalized URI using the normalize function if a base URI was given, then attempts to obtain access to an entity representing the resource identified by the resulting URI, returning the entity as a stream (a Python file-like object). Raises a UriException if the URI scheme is unsupported or if a stream could not be obtained for any reason. """ if baseUri is not None: uri = self.normalize(uri, baseUri) scheme = Uri.GetScheme(uri) else: scheme = Uri.GetScheme(uri) # since we didn't use normalize(), we need to verify here if scheme not in Uri.DEFAULT_URI_SCHEMES: if scheme is None: raise ValueError('When the URI to resolve is a relative ' 'reference, it must be accompanied by a base URI.') else: raise UriException(UriException.UNSUPPORTED_SCHEME, scheme=scheme, resolver=self.__class__.__name__) # Bypass urllib for opening local files. This means we don't get all # the extra metadata that urllib adds to the stream (Last-modified, # Content-Length, a poorly guessed Content-Type, and the URI), but # we also avoid its potentially time-consuming socket.gethostbyname() # calls, which aren't even warranted and are part of urllib's dubious # interpretation of RFC 1738. if scheme == 'file': path = Uri.UriToOsPath(uri, attemptAbsolute=False) try: stream = file(path, 'rb') except IOError, e: raise UriException(UriException.RESOURCE_ERROR, loc='%s (%s)' % (uri, path), uri=uri, msg=str(e))
def Uri2OsPath(context, uri): """ Returns the given URI as an OS path. The result varies depending on the underlying operating system. """ return Uri.UriToOsPath(Conversions.StringValue(uri))
def Test(tester): tester.startGroup('UriDict') tester.startGroup('file:/// and file://localhost/ equivalence') tester.startTest('equivalent key in UriDict') uris = Uri.UriDict() uris['file:///path/to/resource'] = 0 tester.compare(True, 'file://localhost/path/to/resource' in uris, 'RFC 1738 localhost support failed') tester.testDone() tester.startTest('value of 2 equivalent keys') uris = Uri.UriDict() uris['file:///path/to/resource'] = 1 uris['file://localhost/path/to/resource'] = 2 tester.compare(2, uris['file:///path/to/resource'], 'RFC 1738 localhost support failed') tester.testDone() tester.groupDone() tester.startGroup('case equivalence') for uri, expected, junk in caseNormalizationTests: tester.startTest('%s and %s equivalence' % (uri, expected)) uris[uri] = 1 uris[expected] = 2 tester.compare(2, uris[uri]) tester.testDone() tester.groupDone() tester.startGroup('percent-encoding equivalence') for uri, expected in pctEncNormalizationTests: tester.startTest('%s and %s equivalence' % (uri, expected)) uris[uri] = 1 uris[expected] = 2 tester.compare(2, uris[uri]) tester.testDone() tester.groupDone() tester.groupDone() tester.startGroup("PercentEncode and PercentDecode") for unencoded, encoded in percentEncodeTests: if len(unencoded) > 10: test_title = unencoded[:11] + '...' else: test_title = unencoded tester.startTest(repr(test_title)) tester.compare(encoded, Uri.PercentEncode(unencoded)) tester.compare(unencoded, Uri.PercentDecode(encoded)) tester.testDone() # non-BMP tests: # a couple of random chars from U+10000 to U+10FFFD. # # This string will be length 2 or 4 depending on how Python # was built. Either way, it should result in the same percent- # encoded sequence, which should decode back to the original # representation. unencoded = u'\U00010000\U0010FFFD' encoded = u'%F0%90%80%80%F4%8F%BF%BD' tester.startTest("u'\U00010000\U0010FFFD'") tester.compare(encoded, Uri.PercentEncode(unencoded)) tester.compare(unencoded, Uri.PercentDecode(encoded)) tester.testDone() # # This string will be length 4, regardless of how Python was # built. However, if Python was built with wide (UCS-4) chars, # PercentDecode will generate an optimal string (length: 2). unencoded_in = u'\ud800\udc00\udbff\udffd' encoded = u'%F0%90%80%80%F4%8F%BF%BD' unencoded_out = u'\U00010000\U0010FFFD' tester.startTest("u'\ud800\udc00\udbff\udffd'") tester.compare(encoded, Uri.PercentEncode(unencoded_in)) tester.compare(unencoded_out, Uri.PercentDecode(encoded)) tester.testDone() # test a few iso-8859-n variations just to make sure # iso-8859-1 isn't special unencoded = ''.join(map(chr, range(256))) encoded = '%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F' \ '%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F' \ '%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F' \ '0123456789%3A%3B%3C%3D%3E%3F%40' \ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60' \ 'abcdefghijklmnopqrstuvwxyz%7B%7C%7D~' \ '%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F' \ '%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F' \ '%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF' \ '%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF' \ '%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF' \ '%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF' \ '%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF' \ '%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF' for part in (1, 2, 3, 15): enc_name = 'iso-8859-%d' % part tester.startTest(enc_name) try: codecs.lookup(enc_name) except LookupError: tester.warning('Not supported on this platform') tester.testDone() continue tester.compare(encoded, Uri.PercentEncode(unencoded, encoding=enc_name)) tester.compare(unencoded, Uri.PercentDecode(encoded, encoding=enc_name)) tester.testDone() # utf-16be: why not? unencoded = u'a test string...\x00\xe9...\x20\x22...\xd8\x00\xdc\x00' encoded = u'a%20test%20string...\u00e9...%20%22...%D8%00%DC%00' tester.groupDone() tester.startGroup("PublicIdToUrn") for publicid, urn in publicIdTests: tester.startTest(publicid) tester.compare(urn, Uri.PublicIdToUrn(publicid)) tester.testDone() tester.groupDone() tester.startGroup("UrnToPublicId") for publicid, urn in publicIdTests: tester.startTest(urn) tester.compare(publicid, Uri.UrnToPublicId(urn)) tester.testDone() tester.groupDone() tester.startGroup("URI reference syntax") for testuri in good_URI_references: tester.startTest("Good URI ref: %s" % repr(testuri)) tester.compare(1, Uri.MatchesUriRefSyntax(testuri), "Mistakenly tests as invalid") tester.testDone() for testuri in bad_URI_references: tester.startTest("Bad URI ref: %s" % repr(testuri)) tester.compare(0, Uri.MatchesUriRefSyntax(testuri), "Mistakenly tests as valid") tester.testDone() tester.groupDone() tester.startGroup('Absolutize') for uriRef, baseUri, expectedUri in absolutize_test_cases: tester.startTest('base=%r ref=%r' % (baseUri, uriRef)) res = Uri.Absolutize(uriRef, baseUri) # in a couple cases, there's more than one correct result if isinstance(expectedUri, tuple): tester.compare(1, res in expectedUri, 'Invalid result') else: tester.compare(expectedUri, res, 'Invalid result') tester.testDone() tester.groupDone() tester.startGroup('Relativize') for targetUri, againstUri, relativeUri, subPathUri in relativize_test_cases: tester.startTest('target=%r against=%r (subPathOnly=False)' % (targetUri, againstUri)) res = Uri.Relativize(targetUri, againstUri) tester.compare(relativeUri, res, 'Invalid result') tester.testDone() if res is not None: tester.startTest( 'target=%r against=%r (subPathOnly=False, Absolutize)' % (targetUri, againstUri)) res = Uri.Absolutize(res, againstUri) tester.compare(res, targetUri, 'Invalid result') tester.testDone() tester.startTest('target=%r against=%r (subPathOnly=True)' % (targetUri, againstUri)) res = Uri.Relativize(targetUri, againstUri, True) tester.compare(subPathUri, res, 'Invalid result') tester.testDone() if res is not None: tester.startTest( 'target=%r against=%r (subPathOnly=True, Absolutize)' % (targetUri, againstUri)) res = Uri.Absolutize(res, againstUri) tester.compare(res, targetUri, 'Invalid result') tester.testDone() tester.groupDone() tester.startGroup('BaseJoin') for base, relative, expectedUri in basejoin_test_cases: tester.startTest('base=%r rel=%r' % (base, relative)) res = Uri.BaseJoin(base, relative) tester.compare(expectedUri, res, 'Invalid result') tester.testDone() tester.groupDone() tester.startGroup('UriToOsPath') for osname in ('posix', 'nt'): tester.startGroup(osname) for subgroupname in ('absolute', 'relative'): tester.startGroup(subgroupname) for uri, nt_path, posix_path in fileUris: if subgroupname == 'relative': if uri[:5] == 'file:': uri = uri[5:] else: break if isinstance(uri, unicode): testname = repr(uri) else: testname = uri tester.startTest(testname) if osname == 'nt': path = nt_path elif osname == 'posix': path = posix_path else: break if path is None: tester.testException(Uri.UriToOsPath, (uri, ), Uri.UriException, kwargs={ 'attemptAbsolute': False, 'osname': osname }) else: tester.compare( path, Uri.UriToOsPath(uri, attemptAbsolute=False, osname=osname)) tester.testDone() tester.groupDone() tester.groupDone() tester.groupDone() tester.startGroup('OsPathToUri') for osname in ('posix', 'nt'): tester.startGroup(osname) for path, nt_uri, posix_uri in filePaths: if isinstance(path, unicode): testname = repr(path) else: testname = path tester.startTest(testname) if osname == 'nt': uri = nt_uri elif osname == 'posix': uri = posix_uri else: break if uri is None: tester.testException(Uri.OsPathToUri, (path, ), Uri.UriException, kwargs={ 'attemptAbsolute': False, 'osname': osname }) else: tester.compare( uri, Uri.OsPathToUri(path, attemptAbsolute=False, osname=osname)) tester.testDone() tester.groupDone() tester.groupDone() tester.startGroup('NormalizeCase') for uri, expected0, expected1 in caseNormalizationTests: testname = uri uri = Uri.SplitUriRef(uri) tester.startTest(testname) tester.compare(expected0, Uri.UnsplitUriRef(Uri.NormalizeCase(uri))) tester.testDone() tester.startTest(testname + ' (host too)') tester.compare(expected1, Uri.UnsplitUriRef(Uri.NormalizeCase(uri, doHost=1))) tester.testDone() tester.groupDone() tester.startGroup('NormalizePercentEncoding') for uri, expected in pctEncNormalizationTests: testname = uri tester.startTest(testname) tester.compare(expected, Uri.NormalizePercentEncoding(uri)) tester.testDone() tester.groupDone() tester.startGroup('NormalizePathSegments') for path, expected in pathSegmentNormalizationTests: testname = path tester.startTest(testname) tester.compare(expected, Uri.NormalizePathSegments(path)) tester.testDone() tester.groupDone() tester.startGroup('NormalizePathSegmentsInUri') for path, expectedpath in pathSegmentNormalizationTests: # for non-hierarchical scheme, no change expected in every case uri = 'urn:bogus:%s?a=1&b=2#frag' % path expected = 'urn:bogus:%s?a=1&b=2#frag' % path testname = uri tester.startTest(testname) tester.compare(expected, Uri.NormalizePathSegmentsInUri(uri)) tester.testDone() for path, expectedpath in pathSegmentNormalizationTests: if path[:1] == '/': # hierarchical scheme uri = 'file://*****:*****@host%s?a=1&b=2#frag' % path expected = 'file://*****:*****@host%s?a=1&b=2#frag' % expectedpath testname = uri tester.startTest(testname) tester.compare(expected, Uri.NormalizePathSegmentsInUri(uri)) tester.testDone() tester.groupDone() tester.startGroup("MakeUrllibSafe") tests = makeUrllibSafeTests if os.name == 'nt': tests += winMakeUrllibSafeTests for uri, expected in makeUrllibSafeTests: if isinstance(uri, unicode): test_title = repr(uri) else: test_title = uri tester.startTest(test_title) res = Uri.MakeUrllibSafe(uri) tester.compare(expected, res) tester.testDone() tester.groupDone() tester.startGroup("Basic Uri Resolver") data = [ ('http://foo.com/root/', 'path', 'http://foo.com/root/path'), ('http://foo.com/root', 'path', 'http://foo.com/path'), ] for base, uri, exp in data: tester.startTest("normalize: %s %s" % (base, uri)) res = Uri.BASIC_RESOLVER.normalize(uri, base) tester.compare(exp, res) tester.testDone() base = 'foo:foo.com' uri = 'path' tester.startTest("normalize: %s %s" % (base, uri)) tester.testException(Uri.BASIC_RESOLVER.normalize, (uri, base), Uri.UriException) tester.testDone() tester.startTest('resolve') base = os.getcwd() if base[-1] != os.sep: base += os.sep stream = Uri.BASIC_RESOLVER.resolve('test.py', Uri.OsPathToUri(base)) tester.compare(TEST_DOT_PY_BANGPATH, string.rstrip(stream.readline())) stream.close() tester.testDone() tester.startTest('generate') uuid = Uri.BASIC_RESOLVER.generate() tester.compare('urn:uuid:', uuid[:9]) tester.testDone() tester.groupDone() tester.startGroup("SchemeRegistryResolver") def evalSchemeHandler(uri, base=None): if base: uri = base + uri uri = uri[5:] return str(eval(uri)) def shiftSchemeHandler(uri, base=None): if base: uri = base + uri uri = uri[6:] return ''.join([chr(ord(c) + 1) for c in uri]) resolver = SchemeRegistryResolver({ 'eval': evalSchemeHandler, 'shift': shiftSchemeHandler, }) scheme_cases = [ (None, 'eval:150-50', '100'), (None, 'shift:abcde', 'bcdef'), ('eval:150-', '50', '100'), ('shift:ab', 'cde', 'bcdef'), ] for base, relative, expected in scheme_cases: tester.startTest("URI: base=%s uri=%s" % (base, relative)) res = resolver.resolve(relative, base) tester.compare(expected, res) tester.testDone() resolver.handlers[None] = shiftSchemeHandler del resolver.handlers['shift'] for base, relative, expected in scheme_cases: tester.startTest("URI: base=%s uri=%s" % (base, relative)) res = resolver.resolve(relative, base) tester.compare(expected, res) tester.testDone() tester.groupDone() return
sheet_1 = """<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:import href="null.xslt"/> </xsl:transform> """ sheet_2 = """<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:variable name='spam' select='"original"'/> <xsl:import href='Xml/Xslt/Core/addr_book3.xsl'/> </xsl:stylesheet> """ expected_1 = """<?xml version="1.0" encoding="UTF-8"?>\n""" from Ft.Lib import Uri INC_PATH = Uri.UriToOsPath('Xml/Xslt/Core/etc/', attemptAbsolute=1) INC_PATH = Uri.OsPathToUri(INC_PATH) def Test(tester): source = test_harness.FileInfo(string="<foo/>") sheet = test_harness.FileInfo(string=sheet_1) test_harness.XsltTest(tester, source, [sheet], expected_1, stylesheetAltUris=[INC_PATH], title="xsl:import using alternative stylesheet URIs") return
class DocumentElement(XsltElement): """ For the basic specification, see: http://www.exslt.org/exsl/elements/document/index.html The only URI scheme supported by 4Suite currently is 'file:' Security note: As a precaution, if you try to overwrite an existing file, it will be saved to a temporary file (there will be a warning with the file name). If this this precaution fails, the instruction will abort. You can override this precaution, always allowing the function to overwrite a document by using the f:overwrite-okay extension attribute. """ content = ContentInfo.Template legalAttrs = { 'href' : AttributeInfo.UriReferenceAvt(required=1), 'method' : AttributeInfo.QNameAvt(), 'version' : AttributeInfo.NMTokenAvt(), 'encoding' : AttributeInfo.StringAvt(), 'omit-xml-declaration' : AttributeInfo.YesNoAvt(), 'standalone' : AttributeInfo.YesNoAvt(), 'doctype-public' : AttributeInfo.StringAvt(), 'doctype-system' : AttributeInfo.StringAvt(), 'cdata-section-elements' : AttributeInfo.QNamesAvt(), 'indent' : AttributeInfo.YesNoAvt(), 'media-type' : AttributeInfo.StringAvt(), 'f:overwrite-safeguard' : AttributeInfo.YesNoAvt( default='no', description='Whether or not to make backup copies of any file before it\'s overwritten.'), 'f:utfbom' : AttributeInfo.YesNoAvt( default='no', description='Whether to force output of a byte order mark (BOM). Usually used to generate a UTF-8 BOM. Do not use this unless you\'re sure you know what you\'re doing'), } doesSetup = True def setup(self): self._output_parameters = OutputParameters.OutputParameters() return def instantiate(self, context, processor): context.processorNss = self.namespaces context.currentInstruction = self # this uses attributes directly from self self._output_parameters.avtParse(self, context) href = self._href.evaluate(context) if Uri.IsAbsolute(href): uri = href else: try: uri = Uri.Absolutize(href, Uri.OsPathToUri(processor.writer.getStream().name)) except Exception, e: raise XsltRuntimeException( ExsltError.NO_EXSLTDOCUMENT_BASE_URI, context.currentInstruction, href) path = Uri.UriToOsPath(uri) if (self.attributes.get((FT_EXT_NAMESPACE, 'overwrite-safeguard') == u'yes') and os.access(path, os.F_OK)): # Kick in the safety measures # FIXME: Security hole. Switch to the mkstemp as soon as we # mandate Python 2.3 mnimum savefile = tempfile.mktemp('', os.path.split(path)[-1]+'-') processor.warn("The file you are trying to create with" " exsl:document already exists. As a safety" " measure it will be copied to a temporary file" " '%s'." % savefile) #FIXME: l10n try: shutil.copyfile(path, savefile) except: raise XsltRuntimeException( ExsltError.ABORTED_EXSLDOCUMENT_OVERWRITE, context.currentInstruction, path, savefile) try: stream = open(path, 'w') except IOError: dirname = os.path.dirname(path) # Should we also check base path writability with os.W_OK? if not os.access(dirname, os.F_OK): os.makedirs(dirname) stream = open(path, 'w') else: raise processor.addHandler(self._output_parameters, stream) try: self.processChildren(context, processor) finally: processor.removeHandler() stream.close() return
def gather_includes(fullurl): if fullurl not in _includes: _includes[fullurl] = Uri.UriToOsPath(fullurl) self.find_xml_includes(fullurl, _includes) return