On Sunday, December 2, 2012 11:37:43 AM UTC-5, Chris wrote:
> On Sunday, December 2, 2012 8:41:49 AM UTC-5, Anthony wrote:
>
>> Also, note that your solution will work specifically when using the
>> generic.json view because that view does not require any of the
>> response._vars values to be added to response._view_environment (because
>> the view processes response._vars directly). But that solution will cause
>> rendering of HTML views (and other views that rely on
>> response._view_environment) to fail.
>
>
>
> I'm not sure that's true. response._vars is set before the lines I
> commented out:
>
No, my point is that commenting out the lines that update the view
environment doesn't affect your particular case (i.e., execution of the
generic.json view) because generic.json accesses response._vars directly
(which you did not comment out) and therefore does not depend on the
keys/values returned by the function being added to the view environment.
For HTML views, the view typically does depend on the keys/values returned
by the function being added to the view environment, so your solution will
cause the typical HTML view to fail (unless you access all values returned
by the function via response._vars rather than expecting them to be in the
global environment).
> if isinstance(page, dict):
> response._vars = page
> ## for key in page:
> ## response._view_environment[key] = page[key]
>
>
> This isn't a super-strong proof, but I commented out all 3 instances of
> the above in main.py and compileapp.py and so far nothing bad has happened
> :) My web site and APIs stil function as they did before.
>
First, the two instances in compileapp.py are related to the LOAD helper,
so nothing will happen there unless you are using LOAD somewhere. As for
nothing bad happening, I can only assume that is because you don't have any
views that access the keys/values returned by any functions (which would be
the case if you're just using the various generic views, which all access
the keys/values returned by the function via response._vars directly, which
you have not commented out).
Try going to the home page of the "welcome" app. Instead of seeing the
usual home page, you should get a mostly empty page with just "message:
Hello World" on it. That is because the {{if 'message' in globals():}}
condition in /views/index.html will be false with your change, and instead
it proceeds to the {{else:}} clause, which executes
{{=BEAUTIFY(response._vars)}}.
> Searching through all the source of 1.99.7, it isn't obvious where
> _view_environment is used to obtain the response variables.
>
Note, the very next line after the ones you have commented is:
run_view_in(response._view_environment)
The view is executed in response._view_environment (i.e., in an environment
in which all the keys in response._view_environment are available as global
variables). If you don't add the keys/values from the function to
response._view_environment, then they won't be available as global
variables in the view. You can do it that way if you want, but then you'll
have to access all keys/value via response._vars instead.
However the risk that someone would innocently return a dict that has keys
> in common with the env seems pretty high. The 129 keys include a lot of
> common words.
>
I think the risk is mainly with using the generic.json and generic.xml
views, not with the typical HTML views. You only have to avoid overwriting
the web2py API keywords, most of which are HTML helpers (all-caps versions
of HTML tags) and validators (all-caps keywords, mostly starting with
"IS_"). The others to avoid are things like "request", "response",
"redirect", "session", "cache", "Field", but in most cases, it won't be a
problem to overwrite those as long as the view doesn't need to access them.
The only one you really can't overwrite is "response" because run_view_in()
needs to access response.view. In general, I don't think this is a big
problem, as I've never seen anyone complain about it.
> I don't think it's practical to restrict the keys allowable in a dict to
> render. A lot of times the keys will be data-driven (result of user input
> or DB queries) so there isn't a good way to avoid keyword collisions.
>
I agree, but the problem is only with top-level keys, and in that case, you
should generate the JSON or XML directly in the controller and return it
from there rather than using a view to doing the generation.
Anthony
--