Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
8997c967
Commit
8997c967
authored
Oct 26, 2001
by
matt@zope.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Document Template accelerations and additonal C Security Manager accelerations
from cAccessControl-review-branch.
parent
a7131d9f
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
991 additions
and
215 deletions
+991
-215
doc/CHANGES.txt
doc/CHANGES.txt
+5
-0
doc/ENVIRONMENT.txt
doc/ENVIRONMENT.txt
+10
-0
lib/python/AccessControl/DTML.py
lib/python/AccessControl/DTML.py
+21
-5
lib/python/AccessControl/PermissionRole.py
lib/python/AccessControl/PermissionRole.py
+2
-2
lib/python/AccessControl/SecurityManagement.py
lib/python/AccessControl/SecurityManagement.py
+15
-15
lib/python/AccessControl/SecurityManager.py
lib/python/AccessControl/SecurityManager.py
+46
-24
lib/python/AccessControl/ZopeGuards.py
lib/python/AccessControl/ZopeGuards.py
+36
-24
lib/python/AccessControl/ZopeSecurityPolicy.py
lib/python/AccessControl/ZopeSecurityPolicy.py
+29
-5
lib/python/AccessControl/cAccessControl.c
lib/python/AccessControl/cAccessControl.c
+679
-33
lib/python/DocumentTemplate/DT_If.py
lib/python/DocumentTemplate/DT_If.py
+4
-4
lib/python/DocumentTemplate/DT_Var.py
lib/python/DocumentTemplate/DT_Var.py
+8
-4
lib/python/DocumentTemplate/cDocumentTemplate.c
lib/python/DocumentTemplate/cDocumentTemplate.c
+136
-99
No files found.
doc/CHANGES.txt
View file @
8997c967
...
...
@@ -89,6 +89,11 @@ Zope Changes
- API help topics can now document functions as well as classes.
- Security accelerations in c
- Accelerated C Document Template handling; Document Templates
can now do additional rendering in C, improving performance.
Bugs fixed
- WebDAV: Zope escaped nested object properties derived from
...
...
doc/ENVIRONMENT.txt
View file @
8997c967
...
...
@@ -148,6 +148,16 @@ Security issues
2.5+)
ZSP_OWNEROUS_SKIP
If set, will cause the Zope Security Policy to skip checks relating
to ownership, for servers on which ownership is not important.
ZSP_AUTHENTICATED_SKIP
If set, will cause the Zope Security Policy to skip checks relating
to authentication, for servers which serve only anonymous content.
DISALLOW_LOCAL_PRODUCTS
unknown
...
...
lib/python/AccessControl/DTML.py
View file @
8997c967
...
...
@@ -84,26 +84,42 @@
##############################################################################
'''Add security system support to Document Templates
$Id: DTML.py,v 1.
7 2001/06/21 17:16:31 shane
Exp $'''
__version__
=
'$Revision: 1.
7
$'
[
11
:
-
2
]
$Id: DTML.py,v 1.
8 2001/10/26 16:07:50 matt
Exp $'''
__version__
=
'$Revision: 1.
8
$'
[
11
:
-
2
]
from
DocumentTemplate
import
DT_Util
import
SecurityManagement
,
string
,
math
,
whrandom
,
random
import
DocumentTemplate.sequence
from
ZopeGuards
import
guarded_getattr
,
guarded_getitem
,
_marker
from
ZopeGuards
import
guarded_getattr
,
guarded_getitem
class
RestrictedDTML
:
'''
A mix-in for derivatives of DT_String.String that adds Zope security.
'''
def
guarded_getattr
(
self
,
ob
,
name
,
default
=
_marker
):
return
guarded_getattr
(
ob
,
name
,
default
)
def
guarded_getattr
(
self
,
*
args
):
# ob, name [, default]
return
guarded_getattr
(
*
args
)
def
guarded_getitem
(
self
,
ob
,
index
):
return
guarded_getitem
(
ob
,
index
)
try
:
#raise ImportError
import
os
if
os
.
environ
.
get
(
"ZOPE_SECURITY_POLICY"
,
None
)
==
"PYTHON"
:
raise
ImportError
# :)
from
cAccessControl
import
RestrictedDTMLMixin
except
ImportError
:
pass
else
:
class
RestrictedDTML
(
RestrictedDTMLMixin
,
RestrictedDTML
):
'''
A mix-in for derivatives of DT_String.String that adds Zope security.
'''
# Allow access to unprotected attributes
DT_Util
.
TemplateDict
.
__allow_access_to_unprotected_subobjects__
=
1
string
.
__allow_access_to_unprotected_subobjects__
=
1
...
...
lib/python/AccessControl/PermissionRole.py
View file @
8997c967
...
...
@@ -85,8 +85,8 @@
__doc__
=
'''Objects that implement Permission-based roles.
$Id: PermissionRole.py,v 1.1
2 2001/10/19 15:12:25 shane
Exp $'''
__version__
=
'$Revision: 1.1
2
$'
[
11
:
-
2
]
$Id: PermissionRole.py,v 1.1
3 2001/10/26 16:07:50 matt
Exp $'''
__version__
=
'$Revision: 1.1
3
$'
[
11
:
-
2
]
_use_python_impl
=
0
import
os
...
...
lib/python/AccessControl/SecurityManagement.py
View file @
8997c967
...
...
@@ -85,8 +85,21 @@
__doc__
=
'''short description
$Id: SecurityManagement.py,v 1.4 2001/07/02 16:29:55 evan Exp $'''
__version__
=
'$Revision: 1.4 $'
[
11
:
-
2
]
$Id: SecurityManagement.py,v 1.5 2001/10/26 16:07:50 matt Exp $'''
__version__
=
'$Revision: 1.5 $'
[
11
:
-
2
]
def
getSecurityManager
():
"""Get a security manager, for the current thread.
"""
thread_id
=
get_ident
()
manager
=
_managers
.
get
(
thread_id
,
None
)
if
manager
is
None
:
manager
=
SecurityManager
(
thread_id
,
SecurityContext
(
SpecialUsers
.
nobody
))
_managers
[
thread_id
]
=
manager
return
manager
import
SpecialUsers
from
SecurityManager
import
SecurityManager
...
...
@@ -110,19 +123,6 @@ def noSecurityManager():
except
:
pass
def
getSecurityManager
():
"""Get a security manager, for the current thread.
"""
thread_id
=
get_ident
()
manager
=
_managers
.
get
(
thread_id
,
None
)
if
manager
is
None
:
manager
=
SecurityManager
(
thread_id
,
SecurityContext
(
SpecialUsers
.
nobody
))
_managers
[
thread_id
]
=
manager
return
manager
def
setSecurityPolicy
(
aSecurityPolicy
):
"""Set the system default security policy.
...
...
lib/python/AccessControl/SecurityManager.py
View file @
8997c967
...
...
@@ -85,8 +85,8 @@
__doc__
=
'''short description
$Id: SecurityManager.py,v 1.
7 2001/10/19 15:12:25 shane
Exp $'''
__version__
=
'$Revision: 1.
7
$'
[
11
:
-
2
]
$Id: SecurityManager.py,v 1.
8 2001/10/26 16:07:50 matt
Exp $'''
__version__
=
'$Revision: 1.
8
$'
[
11
:
-
2
]
import
ZopeSecurityPolicy
,
os
,
string
...
...
@@ -95,7 +95,12 @@ _noroles = ZopeSecurityPolicy._noroles
try
:
max_stack_size
=
string
.
atoi
(
os
.
environ
.
get
(
'Z_MAX_STACK_SIZE'
,
'100'
))
except
:
max_stack_size
=
100
_defaultPolicy
=
ZopeSecurityPolicy
.
ZopeSecurityPolicy
()
if
os
.
environ
.
has_key
(
"ZSP_OWNEROUS_SKIP"
):
ownerous
=
0
else
:
ownerous
=
1
if
os
.
environ
.
has_key
(
"ZSP_AUTHENTICATION_SKIP"
):
authenticated
=
0
else
:
authenticated
=
1
_defaultPolicy
=
ZopeSecurityPolicy
.
ZopeSecurityPolicy
(
ownerous
=
ownerous
,
authenticated
=
authenticated
)
def
setSecurityPolicy
(
aSecurityPolicy
):
"""Set the system default security policy.
...
...
@@ -107,6 +112,7 @@ def setSecurityPolicy(aSecurityPolicy):
_defaultPolicy
=
aSecurityPolicy
return
last
class
SecurityManager
:
"""A security manager provides methods for checking access and managing
executable context and policies
...
...
@@ -116,35 +122,34 @@ class SecurityManager:
'validate'
:
1
,
'validateValue'
:
1
,
'checkPermission'
:
1
,
'getUser'
:
1
,
'calledByExecutable'
:
1
}
def
__init__
(
self
,
thread_id
,
context
):
self
.
_thread_id
=
thread_id
self
.
_context
=
context
self
.
_policy
=
None
self
.
_policy
=
_defaultPolicy
def
validate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
roles
=
_noroles
):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
roles -- The roles of the object if already known.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
policy
=
self
.
_policy
if
policy
is
None
:
policy
=
_defaultPolicy
if
roles
is
_noroles
:
return
policy
.
validate
(
accessed
,
container
,
name
,
value
,
self
.
_context
)
...
...
@@ -153,19 +158,19 @@ class SecurityManager:
self
.
_context
,
roles
)
def
DTMLValidate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
md
=
None
):
value
=
None
,
md
=
None
):
"""Validate access.
* THIS EXISTS FOR DTML COMPATIBILITY *
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
md -- multidict for DTML (ignored)
...
...
@@ -177,7 +182,6 @@ class SecurityManager:
"""
policy
=
self
.
_policy
if
policy
is
None
:
policy
=
_defaultPolicy
return
policy
.
validate
(
accessed
,
container
,
name
,
value
,
self
.
_context
)
...
...
@@ -185,7 +189,6 @@ class SecurityManager:
"""Convenience for common case of simple value validation.
"""
policy
=
self
.
_policy
if
policy
is
None
:
policy
=
_defaultPolicy
if
roles
is
_noroles
:
return
policy
.
validate
(
None
,
None
,
None
,
value
,
self
.
_context
)
...
...
@@ -198,13 +201,12 @@ class SecurityManager:
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
policy
=
self
.
_policy
if
policy
is
None
:
policy
=
_defaultPolicy
return
policy
.
checkPermission
(
permission
,
object
,
self
.
_context
)
...
...
@@ -218,7 +220,10 @@ class SecurityManager:
raise
SystemError
,
'Excessive recursion'
stack
.
append
(
anExecutableObject
)
p
=
getattr
(
anExecutableObject
,
'_customSecurityPolicy'
,
None
)
if
p
is
not
None
:
p
=
p
()
if
p
is
not
None
:
p
=
p
()
else
:
p
=
_defaultPolicy
self
.
_policy
=
p
def
removeContext
(
self
,
anExecutableObject
,
...
...
@@ -245,10 +250,13 @@ class SecurityManager:
if
stack
:
top
=
stack
[
-
1
]
p
=
getattr
(
top
,
'_customSecurityPolicy'
,
None
)
if
p
is
not
None
:
p
=
p
()
if
p
is
not
None
:
p
=
p
()
else
:
p
=
_defaultPolicy
self
.
_policy
=
p
else
:
self
.
_policy
=
None
self
.
_policy
=
_defaultPolicy
def
getUser
(
self
):
"""Get the current authenticated user"""
...
...
@@ -260,3 +268,17 @@ class SecurityManager:
return
len
(
self
.
_context
.
stack
)
try
:
#raise ImportError
import
os
if
os
.
environ
.
get
(
"ZOPE_SECURITY_POLICY"
,
None
)
==
"PYTHON"
:
raise
ImportError
# :)
from
cAccessControl
import
SecurityManager
as
cSecurityManager
except
ImportError
:
pass
else
:
class
SecurityManager
(
cSecurityManager
,
SecurityManager
):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
lib/python/AccessControl/ZopeGuards.py
View file @
8997c967
...
...
@@ -83,7 +83,7 @@
#
##############################################################################
__version__
=
'$Revision: 1.
7
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
8
$'
[
11
:
-
2
]
from
RestrictedPython.Guards
import
safe_builtins
,
_full_read_guard
,
\
full_write_guard
...
...
@@ -98,29 +98,41 @@ _marker = [] # Create a new marker object.
safe_builtins
=
safe_builtins
.
copy
()
safe_builtins
.
update
(
utility_builtins
)
def
aq_validate
(
inst
,
obj
,
name
,
v
,
validate
):
return
validate
(
inst
,
obj
,
name
,
v
)
def
guarded_getattr
(
inst
,
name
,
default
=
_marker
):
if
name
[:
1
]
!=
'_'
:
# Try to get the attribute normally so that unusual
# exceptions are caught early.
try
:
v
=
getattr
(
inst
,
name
)
except
AttributeError
:
if
default
is
not
_marker
:
return
default
raise
if
Containers
(
type
(
inst
)):
# Simple type. Short circuit.
return
v
validate
=
getSecurityManager
().
validate
# Filter out the objects we can't access.
if
hasattr
(
inst
,
'aq_acquire'
):
return
inst
.
aq_acquire
(
name
,
aq_validate
,
validate
)
# Or just try to get the attribute directly.
if
validate
(
inst
,
inst
,
name
,
v
):
return
v
raise
Unauthorized
,
name
try
:
#raise ImportError
import
os
if
os
.
environ
.
get
(
"ZOPE_SECURITY_POLICY"
,
None
)
==
"PYTHON"
:
raise
ImportError
# :)
from
cAccessControl
import
aq_validate
,
guarded_getattr
except
ImportError
:
def
aq_validate
(
inst
,
obj
,
name
,
v
,
validate
):
return
validate
(
inst
,
obj
,
name
,
v
)
def
guarded_getattr
(
inst
,
name
,
default
=
_marker
):
if
name
[:
1
]
!=
'_'
:
# Try to get the attribute normally so that unusual
# exceptions are caught early.
try
:
v
=
getattr
(
inst
,
name
)
except
AttributeError
:
if
default
is
not
_marker
:
return
default
raise
if
Containers
(
type
(
inst
)):
# Simple type. Short circuit.
return
v
validate
=
getSecurityManager
().
validate
# Filter out the objects we can't access.
if
hasattr
(
inst
,
'aq_acquire'
):
return
inst
.
aq_acquire
(
name
,
aq_validate
,
validate
)
# Or just try to get the attribute directly.
if
validate
(
inst
,
inst
,
name
,
v
):
return
v
raise
Unauthorized
,
name
safe_builtins
[
'getattr'
]
=
guarded_getattr
def
guarded_hasattr
(
object
,
name
):
...
...
lib/python/AccessControl/ZopeSecurityPolicy.py
View file @
8997c967
...
...
@@ -85,8 +85,8 @@
__doc__
=
'''Define Zope
\
'
s default security policy
$Id: ZopeSecurityPolicy.py,v 1.1
4 2001/10/19 15:12:25 shane
Exp $'''
__version__
=
'$Revision: 1.1
4
$'
[
11
:
-
2
]
$Id: ZopeSecurityPolicy.py,v 1.1
5 2001/10/26 16:07:50 matt
Exp $'''
__version__
=
'$Revision: 1.1
5
$'
[
11
:
-
2
]
_use_python_impl
=
0
...
...
@@ -119,8 +119,32 @@ if _use_python_impl:
class
ZopeSecurityPolicy
:
def
__init__
(
self
,
ownerous
=
1
):
def
__init__
(
self
,
ownerous
=
1
,
authenticated
=
1
):
"""Create a Zope security policy.
Two optional keyword arguments may be provided:
ownerous -- Untrusted users can create code
(e.g. Python scripts or templates),
so check that code owners can access resources.
The argument must have a truth value.
The default is true.
authenticated -- Allow access to resources based on the
privaledges of the authenticated user.
The argument must have a truth value.
The default is true.
This (somewhat experimental) option can be set
to false on sites that allow only public
(unauthenticated) access. An anticipated
scenario is a ZEO configuration in which some
clients allow only public access and other
clients allow full management.
"""
self
.
_ownerous
=
ownerous
self
.
_authenticated
=
authenticated
def
validate
(
self
,
accessed
,
container
,
name
,
value
,
context
,
roles
=
_noroles
,
None
=
None
,
type
=
type
,
IntType
=
type
(
0
),
...
...
@@ -239,7 +263,8 @@ if _use_python_impl:
try
:
if
context
.
user
.
allowed
(
value
,
roles
):
return
1
if
self
.
_authenticated
and
context
.
user
.
allowed
(
value
,
roles
):
return
1
except
AttributeError
:
pass
# We don't want someone to acquire if they can't get an unacquired!
...
...
@@ -254,4 +279,3 @@ if _use_python_impl:
if
type
(
roles
)
is
StringType
:
roles
=
[
roles
]
return
context
.
user
.
allowed
(
object
,
roles
)
lib/python/AccessControl/cAccessControl.c
View file @
8997c967
This diff is collapsed.
Click to expand it.
lib/python/DocumentTemplate/DT_If.py
View file @
8997c967
...
...
@@ -147,8 +147,8 @@ __doc__='''Conditional insertion
variable is not reevaluated.
'''
__rcs_id__
=
'$Id: DT_If.py,v 1.1
6 1999/03/10 00:15:07 klm
Exp $'
__version__
=
'$Revision: 1.1
6
$'
[
11
:
-
2
]
__rcs_id__
=
'$Id: DT_If.py,v 1.1
7 2001/10/26 16:07:50 matt
Exp $'
__version__
=
'$Revision: 1.1
7
$'
[
11
:
-
2
]
from
DT_Util
import
ParseError
,
parse_params
,
name_param
,
str
...
...
@@ -192,7 +192,7 @@ class If:
if
elses
is
not
None
:
sections
.
append
(
elses
)
self
.
simple_form
=
tuple
(
sections
)
self
.
simple_form
=
(
'i'
,)
+
tuple
(
sections
)
class
Unless
:
name
=
'unless'
...
...
@@ -204,7 +204,7 @@ class Unless:
name
,
expr
=
name_param
(
args
,
'unless'
,
1
)
if
expr
is
None
:
cond
=
name
else
:
cond
=
expr
.
eval
self
.
simple_form
=
(
cond
,
None
,
section
.
blocks
)
self
.
simple_form
=
(
'i'
,
cond
,
None
,
section
.
blocks
)
class
Else
(
Unless
):
# The else tag is included for backward compatibility and is deprecated.
...
...
lib/python/DocumentTemplate/DT_Var.py
View file @
8997c967
...
...
@@ -217,8 +217,8 @@ Evaluating expressions without rendering results
'''
# '
__rcs_id__
=
'$Id: DT_Var.py,v 1.4
4 2001/10/02 14:23:32 shane
Exp $'
__version__
=
'$Revision: 1.4
4
$'
[
11
:
-
2
]
__rcs_id__
=
'$Id: DT_Var.py,v 1.4
5 2001/10/26 16:07:50 matt
Exp $'
__version__
=
'$Revision: 1.4
5
$'
[
11
:
-
2
]
from
DT_Util
import
parse_params
,
name_param
,
str
import
re
,
string
,
sys
...
...
@@ -254,7 +254,11 @@ class Var:
if
len
(
args
)
==
1
and
fmt
==
's'
:
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
expr
,
self
.
simple_form
=
(
'v'
,
expr
)
elif
len
(
args
)
==
2
and
fmt
==
's'
and
args
.
has_key
(
'html_quote'
):
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
(
'v'
,
expr
,
'h'
)
def
render
(
self
,
md
):
args
=
self
.
args
...
...
@@ -353,7 +357,7 @@ class Call:
name
,
expr
=
name_param
(
args
,
'call'
,
1
)
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
expr
,
None
self
.
simple_form
=
(
'i'
,
expr
,
None
)
def
url_quote
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
...
...
lib/python/DocumentTemplate/cDocumentTemplate.c
View file @
8997c967
...
...
@@ -84,7 +84,7 @@
****************************************************************************/
static
char
cDocumentTemplate_module_documentation
[]
=
""
"
\n
$Id: cDocumentTemplate.c,v 1.
39 2001/06/21 19:08:59 shane
Exp $"
"
\n
$Id: cDocumentTemplate.c,v 1.
40 2001/10/26 16:07:50 matt
Exp $"
;
#include "ExtensionClass.h"
...
...
@@ -94,7 +94,7 @@ static PyObject *py___call__, *py___roles__, *py_AUTHENTICATED_USER;
static
PyObject
*
py_hasRole
,
*
py__proxy_roles
,
*
py_Unauthorized
;
static
PyObject
*
py_Unauthorized_fmt
,
*
py_guarded_getattr
;
static
PyObject
*
py__push
,
*
py__pop
,
*
py_aq_base
,
*
py_renderNS
;
static
PyObject
*
py___class__
;
static
PyObject
*
py___class__
,
*
html_quote
;
/* ----------------------------------------------------- */
...
...
@@ -398,13 +398,29 @@ static PyObject *
MM_cget
(
MM
*
self
,
PyObject
*
key
,
int
call
)
{
long
i
;
PyObject
*
e
,
*
rr
,
*
tb
;
PyObject
*
e
,
*
rr
;
UNLESS
(
-
1
!=
(
i
=
PyList_Size
(
self
->
data
)))
return
NULL
;
while
(
--
i
>=
0
)
{
e
=
PyList_GetItem
(
self
->
data
,
i
);
if
((
e
=
PyObject_GetItem
(
e
,
key
)))
e
=
PyList_GET_ITEM
(
self
->
data
,
i
);
if
(
PyDict_Check
(
e
))
{
e
=
PyDict_GetItem
(
e
,
key
);
Py_XINCREF
(
e
);
}
else
{
UNLESS
(
e
=
PyObject_GetItem
(
e
,
key
))
{
if
(
PyErr_Occurred
()
==
PyExc_KeyError
)
PyErr_Clear
();
else
return
NULL
;
}
}
if
(
e
)
{
if
(
!
call
)
return
e
;
...
...
@@ -437,17 +453,8 @@ MM_cget(MM *self, PyObject *key, int call)
}
return
e
;
}
PyErr_Fetch
(
&
e
,
&
rr
,
&
tb
);
if
(
e
!=
PyExc_KeyError
)
{
PyErr_Restore
(
e
,
rr
,
tb
);
return
NULL
;
}
Py_XDECREF
(
e
);
Py_XDECREF
(
rr
);
Py_XDECREF
(
tb
);
}
PyErr_SetObject
(
PyExc_KeyError
,
key
);
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
...
...
@@ -726,7 +733,7 @@ static int
render_blocks_
(
PyObject
*
blocks
,
PyObject
*
rendered
,
PyObject
*
md
,
PyObject
*
mda
)
{
PyObject
*
block
;
PyObject
*
block
,
*
t
;
int
l
,
i
,
k
=
0
,
append
;
if
((
l
=
PyList_Size
(
blocks
))
<
0
)
return
-
1
;
...
...
@@ -735,95 +742,123 @@ render_blocks_(PyObject *blocks, PyObject *rendered,
block
=
PyList_GET_ITEM
(((
PyListObject
*
)
blocks
),
i
);
append
=
1
;
if
(
PyTuple_Check
(
block
))
if
(
PyTuple_Check
(
block
)
&&
PyTuple_GET_SIZE
(
block
)
>
1
&&
PyTuple_GET_ITEM
(
block
,
0
)
&&
PyString_Check
(
PyTuple_GET_ITEM
(
block
,
0
)))
{
int
bs
;
switch
(
PyString_AS_STRING
(
PyTuple_GET_ITEM
(
block
,
0
))[
0
])
{
case
'v'
:
/* var */
t
=
PyTuple_GET_ITEM
(
block
,
1
);
bs
=
((
PyTupleObject
*
)
block
)
->
ob_size
;
if
(
bs
==
1
)
{
/* Simple var */
block
=
PyTuple_GET_ITEM
(
block
,
0
);
if
(
PyString_Check
(
block
))
block
=
PyObject_GetItem
(
md
,
block
);
else
block
=
PyObject_CallObject
(
block
,
mda
);
if
(
block
)
ASSIGN
(
block
,
PyObject_Str
(
block
));
UNLESS
(
block
)
return
-
1
;
}
else
{
/* if */
int
icond
,
m
;
PyObject
*
cond
,
*
n
,
*
cache
;
UNLESS
(
cache
=
PyDict_New
())
return
-
1
;
cond
=
PyObject_GetAttr
(
md
,
py__push
);
if
(
cond
)
ASSIGN
(
cond
,
PyObject_CallFunction
(
cond
,
"O"
,
cache
));
Py_DECREF
(
cache
);
if
(
cond
)
Py_DECREF
(
cond
);
else
return
-
1
;
if
(
t
==
NULL
)
return
-
1
;
if
(
PyString_Check
(
t
))
t
=
PyObject_GetItem
(
md
,
t
);
else
t
=
PyObject_CallObject
(
t
,
mda
);
if
(
t
==
NULL
||
(
!
PyString_Check
(
t
)))
{
if
(
t
)
ASSIGN
(
t
,
PyObject_Str
(
t
));
UNLESS
(
t
)
return
-
1
;
}
if
(
PyString_Check
(
t
)
&&
PyTuple_GET_SIZE
(
block
)
==
3
)
/* html_quote */
{
if
(
strchr
(
PyString_AS_STRING
(
t
),
'&'
)
&&
strchr
(
PyString_AS_STRING
(
t
),
'<'
)
&&
strchr
(
PyString_AS_STRING
(
t
),
'>'
)
&&
strchr
(
PyString_AS_STRING
(
t
),
'"'
)
)
ASSIGN
(
t
,
PyObject_CallFunction
(
html_quote
,
"O"
,
t
));
if
(
t
==
NULL
)
return
-
1
;
}
block
=
t
;
break
;
case
'i'
:
/* if */
{
int
icond
,
m
,
bs
;
PyObject
*
cond
,
*
n
,
*
cache
;
bs
=
PyTuple_GET_SIZE
(
block
)
-
1
;
/* subtract code */
UNLESS
(
cache
=
PyDict_New
())
return
-
1
;
cond
=
PyObject_GetAttr
(
md
,
py__push
);
if
(
cond
)
ASSIGN
(
cond
,
PyObject_CallFunction
(
cond
,
"O"
,
cache
));
Py_DECREF
(
cache
);
if
(
cond
)
Py_DECREF
(
cond
);
else
return
-
1
;
append
=
0
;
m
=
bs
-
1
;
for
(
icond
=
0
;
icond
<
m
;
icond
+=
2
)
{
cond
=
PyTuple_GET_ITEM
(
block
,
icond
);
if
(
PyString_Check
(
cond
))
{
/* We have to be careful to handle key errors here */
n
=
cond
;
if
((
cond
=
PyObject_GetItem
(
md
,
cond
)))
{
if
(
PyDict_SetItem
(
cache
,
n
,
cond
)
<
0
)
{
Py_DECREF
(
cond
);
return
if_finally
(
md
,
1
);
}
}
else
{
PyObject
*
t
,
*
v
,
*
tb
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
!=
PyExc_KeyError
||
PyObject_Compare
(
v
,
n
))
{
PyErr_Restore
(
t
,
v
,
tb
);
return
if_finally
(
md
,
1
);
}
Py_XDECREF
(
t
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
cond
=
Py_None
;
Py_INCREF
(
cond
);
}
}
else
UNLESS
(
cond
=
PyObject_CallObject
(
cond
,
mda
))
return
if_finally
(
md
,
1
);
if
(
PyObject_IsTrue
(
cond
))
{
Py_DECREF
(
cond
);
block
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
);
if
(
block
!=
Py_None
&&
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
return
if_finally
(
md
,
1
);
m
=-
1
;
break
;
}
else
Py_DECREF
(
cond
);
}
append
=
0
;
m
=
bs
-
1
;
for
(
icond
=
0
;
icond
<
m
;
icond
+=
2
)
{
cond
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
);
if
(
PyString_Check
(
cond
))
{
/* We have to be careful to handle key errors here */
n
=
cond
;
if
((
cond
=
PyObject_GetItem
(
md
,
cond
)))
{
if
(
PyDict_SetItem
(
cache
,
n
,
cond
)
<
0
)
{
Py_DECREF
(
cond
);
return
if_finally
(
md
,
1
);
}
}
else
{
PyObject
*
t
,
*
v
,
*
tb
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
!=
PyExc_KeyError
||
PyObject_Compare
(
v
,
n
))
{
PyErr_Restore
(
t
,
v
,
tb
);
return
if_finally
(
md
,
1
);
}
Py_XDECREF
(
t
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
cond
=
Py_None
;
Py_INCREF
(
cond
);
}
}
else
UNLESS
(
cond
=
PyObject_CallObject
(
cond
,
mda
))
return
if_finally
(
md
,
1
);
if
(
PyObject_IsTrue
(
cond
))
{
Py_DECREF
(
cond
);
block
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
+
1
);
if
(
block
!=
Py_None
&&
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
return
if_finally
(
md
,
1
);
m
=-
1
;
break
;
}
else
Py_DECREF
(
cond
);
}
if
(
icond
==
m
)
{
block
=
PyTuple_GET_ITEM
(
block
,
icond
);
block
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
);
if
(
block
!=
Py_None
&&
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
return
if_finally
(
md
,
1
);
}
if
(
if_finally
(
md
,
0
)
==
-
2
)
return
-
1
;
}
}
}
break
;
default:
PyErr_Format
(
PyExc_ValueError
,
"Invalid DTML command code, %s"
,
PyString_AS_STRING
(
PyTuple_GET_ITEM
(
block
,
0
)));
return
-
1
;
}
}
else
if
(
PyString_Check
(
block
))
{
Py_INCREF
(
block
);
...
...
@@ -904,10 +939,14 @@ void
initcDocumentTemplate
(
void
)
{
PyObject
*
m
,
*
d
;
char
*
rev
=
"$Revision: 1.
39
$"
;
char
*
rev
=
"$Revision: 1.
40
$"
;
DictInstanceType
.
ob_type
=&
PyType_Type
;
UNLESS
(
html_quote
=
PyImport_ImportModule
(
"html_quote"
))
return
;
ASSIGN
(
html_quote
,
PyObject_GetAttrString
(
html_quote
,
"html_quote"
));
UNLESS
(
html_quote
)
return
;
UNLESS
(
py_isDocTemp
=
PyString_FromString
(
"isDocTemp"
))
return
;
UNLESS
(
py_renderNS
=
PyString_FromString
(
"__render_with_namespace__"
))
return
;
UNLESS
(
py_blocks
=
PyString_FromString
(
"blocks"
))
return
;
...
...
@@ -946,6 +985,4 @@ initcDocumentTemplate(void)
PyDict_SetItemString
(
d
,
"__version__"
,
PyString_FromStringAndSize
(
rev
+
11
,
strlen
(
rev
+
11
)
-
2
));
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module cDocumentTemplate"
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment