Merge lp:~zorba-coders/zorba/bug-988417-block-internal-module into lp:zorba

Proposed by Till Westmann
Status: Superseded
Proposed branch: lp:~zorba-coders/zorba/bug-988417-block-internal-module
Merge into: lp:zorba
Diff against target: 159 lines (+94/-5)
4 files modified
src/compiler/translator/translator.cpp (+5/-0)
src/context/static_context.cpp (+15/-0)
src/context/static_context.h (+9/-0)
test/api/userdefined_uri_resolution.cpp (+65/-5)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug-988417-block-internal-module
Reviewer Review Type Date Requested Status
Chris Hillery Approve
Matthias Brantner Pending
Markos Zaharioudakis Pending
Review via email: mp+103542@code.launchpad.net

This proposal has been superseded by a proposal from 2012-05-01.

Description of the change

Enables a user to disable an built-in module. This is done by adding a collection of blocked modules URIs to the static context. This collection is checked before a built-in module is added to the context in the translator.

To post a comment you must log in.
Revision history for this message
Chris Hillery (ceejatec) wrote :

1. To maintain ABI compatibility, you must only add new virtual functions to the end of public classes.

2. I don't like that this mechanism is so different to the way you block non-internal modules (using a URIMapper with DENY_ACCESS). While it would be a bit less efficient, it would be more consistent to call static_context::resolve_uri() at translator.cpp line 2840 solely for the purpose of seeing if zerr::ZXQP0029_URI_ACCESS_DENIED is thrown.

review: Needs Fixing
Revision history for this message
Matthias Brantner (matthias-brantner) wrote :

I quite like Chris's idea from bullet 2. I don't think it's a big overhead if it's done once per module import.

Revision history for this message
Till Westmann (tillw) wrote :

It seemed to me that the whole point of distinguishing between built-in modules and other modules here was that one does not want to invoke the the existing URI resolution mechanisms. Wanting to keep this spirit of the existing code, I proposed this solution. If that's not needed, then that's fine with me.
(The one thing that I'm not extremely fond of is that we would invoke exceptions to find the answer to a simple question, but I can live with that.)

Obviously going through the URIMapper mechanism would have the great advantage of not forcing the user of the API to find out which modules are "internal" and which ones aren't. This would also make programs written agains this API more robust wrt. to changes in the internal/external classification of modules.

Revision history for this message
Chris Hillery (ceejatec) wrote :

IMHO, the point of "built-in modules" was to prevent the overhead of *compiling* those modules, not bypassing URI resolution per se. It is true, though, that invoking URI resolution implies a bit of performance overhead. I believe that if only the URI mapping stage is invoked that the overhead will be relatively small. It probably is important to bypass the URL Resolution stage, because that's where things like making network connections to download the module might occur.

I agree that using exceptions to communicate results isn't ideal, but I think the code reuse and API consolidation outweighs that concern in this case. However, it would actually be pretty easy to either modify apply_uri_mappers() or provide a slight variant of that method (with appropriate refactoring) which simply checked for DENY_ACCESS and returned a bool instead of throwing an exception. I could do that if you like.

10801. By Till Westmann

implement Chris' proposal to implement blocking using static_context::get_candidate_uris

10802. By Till Westmann

add tests

10803. By Till Westmann

merge trunk

Revision history for this message
Till Westmann (tillw) wrote :

I've changed this as proposed (I think) and added some tests.
Having the exception throw directly seems to have the advantage that I get consistent behavior between internal and external modules - so that seems to be good.

As resolution doesn't seem to happen in the current scenario, the only thing that's still not that nice is that we're updating the vector for something that's in principle a read-only operation. But, as you said, that's probably a minor overhead.

Revision history for this message
Chris Hillery (ceejatec) wrote :

Ah, yes, I guess you want the exception to be thrown anyway. Cool, that works.

review: Approve
10804. By Till Westmann

fix typo

10805. By Till Westmann

update changelog

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/compiler/translator/translator.cpp'
2--- src/compiler/translator/translator.cpp 2012-04-26 13:25:13 +0000
3+++ src/compiler/translator/translator.cpp 2012-05-01 04:51:21 +0000
4@@ -2840,6 +2840,11 @@
5 // importing module that X has been imported.
6 if (atlist == NULL && static_context::is_builtin_module(targetNS))
7 {
8+ // hust a test, this will throw, if the access is denied
9+ std::vector<zstring> candidateURIs;
10+ theRootSctx->get_candidate_uris(targetNS,
11+ internal::EntityData::MODULE,
12+ candidateURIs);
13 theRootSctx->add_imported_builtin_module(targetNS);
14 #ifdef NDEBUG
15 // We cannot skip the math or the sctx introspection modules because they
16
17=== modified file 'src/context/static_context.cpp'
18--- src/context/static_context.cpp 2012-04-27 10:20:33 +0000
19+++ src/context/static_context.cpp 2012-05-01 04:51:21 +0000
20@@ -1526,6 +1526,21 @@
21 }
22 }
23
24+void static_context::get_candidate_uris(
25+ zstring const& aUri,
26+ internal::EntityData::Kind aEntityKind,
27+ std::vector<zstring>& oComponents) const
28+{
29+ // Create a simple EntityData that just reports the specified Kind
30+ internal::EntityData const lData(aEntityKind);
31+
32+ apply_uri_mappers(aUri, &lData, internal::URIMapper::CANDIDATE, oComponents);
33+ if (oComponents.size() == 0)
34+ {
35+ oComponents.push_back(aUri);
36+ }
37+}
38+
39
40 /***************************************************************************//**
41
42
43=== modified file 'src/context/static_context.h'
44--- src/context/static_context.h 2012-04-24 18:22:23 +0000
45+++ src/context/static_context.h 2012-05-01 04:51:21 +0000
46@@ -705,6 +705,15 @@
47 (zstring const& aUri, internal::EntityData::Kind aEntityKind,
48 std::vector<zstring>& oComponents) const;
49
50+ /**
51+ * Given a URI, populate a vector with a list of candidate URIs. If
52+ * no candidate URIs are available, the vector will be populated
53+ * with (only) the input URI.
54+ */
55+ void get_candidate_uris
56+ (zstring const& aUri, internal::EntityData::Kind aEntityKind,
57+ std::vector<zstring>& oComponents) const;
58+
59 void set_uri_path(const std::vector<zstring>& aURIPath);
60
61 void get_uri_path(std::vector<zstring>& oURIPath) const;
62
63=== modified file 'test/api/userdefined_uri_resolution.cpp'
64--- test/api/userdefined_uri_resolution.cpp 2012-04-24 12:39:38 +0000
65+++ test/api/userdefined_uri_resolution.cpp 2012-05-01 04:51:21 +0000
66@@ -79,11 +79,13 @@
67 virtual ~DenyAccessURIMapper() {}
68
69 virtual void mapURI(const zorba::String aUri,
70- EntityData const* aEntityData,
71+ EntityData const*,
72 std::vector<zorba::String>& oUris) throw ()
73 {
74 // Deny access to an URI that would otherwise work
75- if(aUri == "http://www.zorba-xquery.com/tutorials/helloworld.xsd") {
76+ if(aUri == "http://www.zorba-xquery.com/tutorials/helloworld.xsd" ||
77+ aUri == "http://www.zorba-xquery.com/modules/fetch" ||
78+ aUri == "http://expath.org/ns/file") {
79 oUris.push_back(URIMapper::DENY_ACCESS);
80 }
81 }
82@@ -259,7 +261,53 @@
83 return false;
84 }
85
86-bool test_deny_access(Zorba* aZorba)
87+bool test_deny_internal_module_access(Zorba* aZorba)
88+{
89+ StaticContext_t lContext = aZorba->createStaticContext();
90+
91+ DenyAccessURIMapper lMapper;
92+ lContext->registerURIMapper(&lMapper);
93+
94+ try {
95+ XQuery_t lQuery = aZorba->compileQuery
96+ ("import module namespace fetch = "
97+ "'http://www.zorba-xquery.com/modules/fetch'; "
98+ "1 + 1", lContext);
99+ std::cout << lQuery << std::endl;
100+ } catch (ZorbaException& e) {
101+ std::cout << "Caught exception: " << e.what() << std::endl;
102+ if (e.diagnostic() == zerr::ZXQP0029_URI_ACCESS_DENIED) {
103+ std::cout << "...the correct exception!" << std::endl;
104+ return true;
105+ }
106+ }
107+ return false;
108+}
109+
110+bool test_deny_external_module_access(Zorba* aZorba)
111+{
112+ StaticContext_t lContext = aZorba->createStaticContext();
113+
114+ DenyAccessURIMapper lMapper;
115+ lContext->registerURIMapper(&lMapper);
116+
117+ try {
118+ XQuery_t lQuery = aZorba->compileQuery
119+ ("import module namespace file = "
120+ "'http://expath.org/ns/file'; "
121+ "1 + 1", lContext);
122+ std::cout << lQuery << std::endl;
123+ } catch (ZorbaException& e) {
124+ std::cout << "Caught exception: " << e.what() << std::endl;
125+ if (e.diagnostic() == zerr::ZXQP0029_URI_ACCESS_DENIED) {
126+ std::cout << "...the correct exception!" << std::endl;
127+ return true;
128+ }
129+ }
130+ return false;
131+}
132+
133+bool test_deny_schema_access(Zorba* aZorba)
134 {
135 StaticContext_t lContext = aZorba->createStaticContext();
136
137@@ -355,8 +403,20 @@
138 std::cout << " ...failed!" << std::endl;
139 }
140
141- std::cout << "test_deny_access" << std::endl;
142- if (!test_deny_access(lZorba)) {
143+ std::cout << "test_deny_internal_module_access" << std::endl;
144+ if (!test_deny_internal_module_access(lZorba)) {
145+ retval = 1;
146+ std::cout << " ... failed!" << std::endl;
147+ }
148+
149+ std::cout << "test_deny_external_module_access" << std::endl;
150+ if (!test_deny_external_module_access(lZorba)) {
151+ retval = 1;
152+ std::cout << " ... failed!" << std::endl;
153+ }
154+
155+ std::cout << "test_deny_schema_access" << std::endl;
156+ if (!test_deny_schema_access(lZorba)) {
157 retval = 1;
158 std::cout << " ... failed!" << std::endl;
159 }

Subscribers

People subscribed via source and target branches