mirror of
https://github.com/OlafvdSpek/ctemplate.git
synced 2025-09-28 19:05:49 +08:00
* Avoid "unused var" warning in opt mode (mec)
* Use ascii_is*() to avoid langtype issues (csilvers) * Fix 'class not properly dll-exported' warnings (csilvers) * mv README.windows to windows-friendly README-windows.txt (csilvers) * Update README.windows to emphasize $IncludeDir a bit more (csilvers) * Add :I=html, :I=css image URL modifiers (jshneier) * Document the new image URL modifier (dougy) * Update NEWS file to be non-empty (csilvers)
This commit is contained in:
parent
b3b532aa19
commit
8c338f322e
35
INSTALL
35
INSTALL
|
@ -1,3 +1,38 @@
|
|||
Ctemplate-Specific Install Notes
|
||||
================================
|
||||
|
||||
This code should work on any modern C++ system. It has been tested on
|
||||
the following systems:
|
||||
FreeBSD 6.0
|
||||
Linux Fedora Core 3
|
||||
Linux Fedora Core 4
|
||||
Linux Fedora Core 5
|
||||
Linux Fedora Core 6
|
||||
Linux RedHat 9
|
||||
Linux Ubuntu 6.06.1
|
||||
Mac OS X 10.3.9 (Panther)
|
||||
Mac OS X 10.4.8 (Tiger)
|
||||
Solaris 10 (x86)
|
||||
Windows XP, Visual Studio 2003 (VC++7.1)
|
||||
Windows XP, Visual Studio 2005 (VC++8)
|
||||
|
||||
The only known problem is with Mac OS X 10.3.9 (Panther), which may
|
||||
have problems with the export-symbols optimization this library does
|
||||
to limit its exposed API. If you have problems compiling that seem to
|
||||
involve nmedit, the solution is to edit the Makefile and remove all
|
||||
instances of
|
||||
-export-symbols-regex $(CTEMPLATE_TESTING_SYMBOLS)
|
||||
Just remove that string exactly. After that, code should build.
|
||||
|
||||
For Solaris 10 6/06, we have tested only with gcc (not the Sun
|
||||
compiler). To get this to work, and to work around a bug in Solaris,
|
||||
install as follows:
|
||||
% PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin ./configure LDFLAGS="-Lsrc/solaris -lrt"
|
||||
% PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin make
|
||||
|
||||
See README.windows for installation instructions for Windows.
|
||||
|
||||
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
|||
## This is for HTML and other documentation you want to install.
|
||||
## Add your documentation files (in doc/) in addition to these
|
||||
## top-level boilerplate files. Also add a TODO file if you have one.
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README_windows.txt \
|
||||
doc/designstyle.css doc/index.html \
|
||||
doc/howto.html doc/tips.html doc/example.html doc/auto_escape.html \
|
||||
doc/xss_resources.html
|
||||
|
|
|
@ -673,7 +673,7 @@ noinst_HEADERS = \
|
|||
src/ctemplate/template_namelist.h.in \
|
||||
src/ctemplate/per_expand_data.h.in
|
||||
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README_windows.txt \
|
||||
doc/designstyle.css doc/index.html \
|
||||
doc/howto.html doc/tips.html doc/example.html doc/auto_escape.html \
|
||||
doc/xss_resources.html
|
||||
|
|
146
NEWS
146
NEWS
|
@ -0,0 +1,146 @@
|
|||
=== 20 April 2010 ==
|
||||
|
||||
I've just released ctemplate 0.97. This change consists primarily of
|
||||
a significant change to the API: the addition of the `TemplateCache`
|
||||
class, combined with deprecation of the `Template` class.
|
||||
|
||||
`TemplateCache` is a class that holds a collection of templates; this
|
||||
concept always existed in ctemplate, but was not previously exposed.
|
||||
Many static methods of the `Template` class, such as
|
||||
`ReloadAllIfChanged()`, have become methods on `TemplateCache` instead
|
||||
(the `Template` methods have been retained for backwards
|
||||
compatibility.) Other methods, such as `Expand()`, have become free
|
||||
functions. In fact, the entire `Template` class has been deprecated.
|
||||
|
||||
The deprecation of `Template` calls for changes in all clients of the
|
||||
template code -- you can see in the example at the top of this page
|
||||
how the code has changed from `Template* tpl =
|
||||
ctemplate::Template::GetTemplate("example.tpl",
|
||||
ctemplate::DO_NOT_STRIP); tpl->Expand(&output, &dict);` to
|
||||
`ctemplate::ExpandTemplate("example.tpl", ctemplate::DO_NOT_STRIP,
|
||||
&dict, &output);`. These changes will make the code simpler and more
|
||||
thread-safe.
|
||||
|
||||
Old code should continue to work -- the `Template` class remains --
|
||||
but new code should use the new API, and old code should transition as
|
||||
convenient. One old API method is intrinsically thread-unsafe, and
|
||||
should be prioritized to change: `tpl->ReloadIfChanged` should change
|
||||
to `ctemplate::Template::ReloadAllIfChanged()`. Note this is a
|
||||
semantic change: all templates are now reloaded, rather than just one.
|
||||
However, since templates are reloaded lazily, and only if they've
|
||||
changed on disk, I'm hopeful it will always be a reasonable change to
|
||||
make.
|
||||
|
||||
To go along with these changes, the documentation has been almost
|
||||
entirely revamped and made more accessible. Obscure ctemplate
|
||||
features have been excised from the user's guide and moved into a
|
||||
separate reference document. The new API is fully documented,
|
||||
including new flexibility around reloading templates, made available
|
||||
by the introduction of `TemplateCache`.
|
||||
|
||||
There are some more minor changes as well, such as the addition of
|
||||
#include guards in the auto-generated .tpl.h files, to make it safe to
|
||||
multiply-include them. I've also been continuing the portability
|
||||
work: ctemplate should now work under Cygwin and MinGW. A full list
|
||||
of changes is available in the
|
||||
[http://google-ctemplate.googlecode.com/svn/tags/ctemplate-0.97/ChangeLog
|
||||
ChangeLog].
|
||||
|
||||
I know I've said this before, but I don't expect major API changes
|
||||
before the 1.0 release. The most significant changes I expect to see
|
||||
are the potential removal of some of the 'forwarding' methods in the
|
||||
(deprecated) `Template` class.
|
||||
|
||||
=== 12 June 2009 ==
|
||||
|
||||
I've just released ctemplate 0.95. This is entirely an API cleanup
|
||||
release. Actually, relatively little of the API proper has changed:
|
||||
`StringToTemplate` no longer takes an autoescape-context arg (instead
|
||||
you specify this as part of the template-string, using the
|
||||
`AUTOESCAPE` pragma). A few obsolete constructs have gone away, such
|
||||
as the `TemplateFromString` class and
|
||||
`TemplateDictionary::html_escape` and friends (just use the top-level
|
||||
`html_escape`). See the
|
||||
[http://google-ctemplate.googlecode.com/svn/tags/ctemplate-0.95/ChangeLog
|
||||
ChangeLog] for a full list of these changes.
|
||||
|
||||
The biggest change is a renaming: the default namespace is now
|
||||
`ctemplate` rather than `google`, and the include directory is
|
||||
`ctemplate` rather than `google`. Other namespaces, such as
|
||||
`template_modifiers`, have gone away.
|
||||
|
||||
All these changes will require you to modify your old code to get it
|
||||
working with ctemplate 0.95. I've written a
|
||||
[http://google-ctemplate.googlecode.com/svn/trunk/contrib/convert_to_95.pl
|
||||
script] to help you do that. Please open an
|
||||
[http://code.google.com/p/google-ctemplate/issues/list issue] if you
|
||||
see a problem with the script. I've tested it, but not as widely as
|
||||
I'd like. Also note the script will not be perfect for more complex
|
||||
constructs, which you will have to clean up by hand.
|
||||
|
||||
I hope (expect) the API is now stable, and we won't see any more such
|
||||
changes before ctemplate 1.0. I tried to isolate them all in this
|
||||
release; except for the API changes, this release should behave
|
||||
identically to ctemplate 0.94.
|
||||
|
||||
=== 7 May 2009 ===
|
||||
|
||||
I've just released ctemplate 0.94. A few new features have been
|
||||
added, such as the ability to expand a template into your own custom
|
||||
`ExpandEmitter` instance, and the ability to hook the annotation
|
||||
system (typically used for debugging). You can now remove strings
|
||||
from the template cache in addition to adding them. Also, there
|
||||
continues to be a trickle of new modifiers, in this case a modifier
|
||||
for URL's in a CSS context.
|
||||
|
||||
However, the most invasive changes were made for speed reasons. The
|
||||
biggest is that (almost) all `TemplateDictionary` allocations are now
|
||||
done on the arena -- this includes allocations by the STL classes
|
||||
inside the dictionary. This allows us to free all the memory at once,
|
||||
rather than item by item, and has yielded a 3-4% speed improvement in
|
||||
our tests. I've combined this with a `small_map` class that stores
|
||||
items in a vector instead of a hash-map until we get to 3 or 4 items;
|
||||
this gives another speed increase in the (common) case a template has
|
||||
only a few sections or includes.
|
||||
|
||||
I also changed the hashing code to use
|
||||
[http://murmurhash.googlepages.com/ MurmurHash] everywhere, rather
|
||||
than the string hash function built into the STL library. This should
|
||||
be faster.
|
||||
|
||||
All these changes should not be outwardly visible, but they do use
|
||||
more advanced features of C++ than ctemplate has to date. This may
|
||||
result in some problems compiling, or conceivably when running. If
|
||||
you see any, please file an
|
||||
[http://code.google.com/p/google-ctemplate/issues/list issue report].
|
||||
|
||||
You can see a full list of changes on the
|
||||
[http://google-ctemplate.googlecode.com/svn/tags/ctemplate-0.94/ChangeLog
|
||||
ChangeLog].
|
||||
|
||||
=== 20 August 2008 ===
|
||||
|
||||
ctemplate 0.91 introduces the beginning of some API changes, as I look
|
||||
to clean up the API in preparation for ctemplate 1.0. After 1.0, the
|
||||
API will remain backwards compatible, but until that time, the API may
|
||||
change. Please take a look at the
|
||||
[http://google-ctemplate.googlecode.com/svn/trunk/ChangeLog ChangeLog]
|
||||
to see if any of these changes affect you.
|
||||
|
||||
One change is the introduction of a new `PerExpandData` class, which
|
||||
holds some state that was formerly in the `TemplateDictionary` class.
|
||||
I'm still not sure if this class is a good idea, if it should be
|
||||
separate from `TemplateDictionary` or a member, or what functionality
|
||||
should move there (for instance, should `SetTemplateGlobal` move
|
||||
there, since template-global variables are really, in some sense,
|
||||
per-expand variables?) If you have any feedback, ideally based on
|
||||
your own experience using the current API, feel free to post it at
|
||||
`google-ctemplate@googlegroups.com`.
|
||||
|
||||
ctemplate also has several new features, including the addition of
|
||||
"separator" sections, and the ability to change the markup character
|
||||
(from `{{`). See the
|
||||
[http://google-ctemplate.googlecode.com/svn/trunk/ChangeLog ChangeLog]
|
||||
for a complete list, and the
|
||||
[http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html howto
|
||||
documentation] for more details on these new features.
|
|
@ -1,38 +1,43 @@
|
|||
This project has been ported to Windows. A working solution file
|
||||
exists in this directory:
|
||||
google-ctemplate.sln
|
||||
|
||||
You can load this solution file into either VC++ 7.1 (Visual Studio
|
||||
2003) or VC++ 8.0 (Visual Studio 2005) -- in the latter case, it will
|
||||
automatically convert the files to the latest format for you.
|
||||
|
||||
When you build the solution, it will create libctemplate.dll, the main
|
||||
library for this project, plus a number of unittests, which you can
|
||||
run by hand (or, more easily, under the Visual Studio debugger) to
|
||||
make sure everything is working properly on your system. The binaries
|
||||
will end up in a directory called "debug" or "release" in the
|
||||
top-level directory (next to the .sln file).
|
||||
|
||||
If you wish to link to ctemplate statically instead of using the .dll,
|
||||
you can; see the example project template_unittest_static. For this
|
||||
to work, you'll need to add "/D CTEMPLATE_DLL_DECL=" to the compile
|
||||
line of every ctemplate .cc file.
|
||||
|
||||
Note that these systems are set to build in Debug mode by default.
|
||||
You may want to change them to Release mode.
|
||||
|
||||
Currently, Template::StringToTemplate returns a Template object that
|
||||
you, the caller, must free. We've heard reports that Windows can have
|
||||
trouble allocating memory in a .dll that is meant to be freed in the
|
||||
application. Thus, we suggest you not use StringToTemplate from
|
||||
Windows. Instead, you can use Template::StringToTemplateCache()
|
||||
followed by Template::GetTemplate().
|
||||
|
||||
I have little experience with Windows programming, so there may be
|
||||
better ways to set this up than I've done! If you run across any
|
||||
problems, please post to the google-ctemplate Google Group, or report
|
||||
them on the google-ctemplate Google Code site:
|
||||
http://groups.google.com/group/google-ctemplate
|
||||
http://code.google.com/p/google-ctemplate/issues/list
|
||||
|
||||
-- craig
|
||||
This project has been ported to Windows. A working solution file
|
||||
exists in this directory:
|
||||
google-ctemplate.sln
|
||||
|
||||
You can load this solution file into either VC++ 7.1 (Visual Studio
|
||||
2003) or VC++ 8.0 (Visual Studio 2005) -- in the latter case, it will
|
||||
automatically convert the files to the latest format for you.
|
||||
|
||||
When you build the solution, it will create libctemplate.dll, the main
|
||||
library for this project, plus a number of unittests, which you can
|
||||
run by hand (or, more easily, under the Visual Studio debugger) to
|
||||
make sure everything is working properly on your system. The binaries
|
||||
will end up in a directory called "debug" or "release" in the
|
||||
top-level directory (next to the .sln file).
|
||||
|
||||
I don't know very much about how to install DLLs on Windows, so you'll
|
||||
have to figure out that part for yourself. If you choose to just
|
||||
re-use the existing .sln, make sure you set the IncludeDir's
|
||||
appropriately! Look at the properties for libctemplate.dll.
|
||||
|
||||
If you wish to link to ctemplate statically instead of using the .dll,
|
||||
you can; see the example project template_unittest_static. For this
|
||||
to work, you'll need to add "/D CTEMPLATE_DLL_DECL=" to the compile
|
||||
line of every ctemplate .cc file.
|
||||
|
||||
Note that these systems are set to build in Debug mode by default.
|
||||
You may want to change them to Release mode.
|
||||
|
||||
Currently, Template::StringToTemplate returns a Template object that
|
||||
you, the caller, must free. We've heard reports that Windows can have
|
||||
trouble allocating memory in a .dll that is meant to be freed in the
|
||||
application. Thus, we suggest you not use StringToTemplate from
|
||||
Windows. Instead, you can use Template::StringToTemplateCache()
|
||||
followed by Template::GetTemplate().
|
||||
|
||||
I have little experience with Windows programming, so there may be
|
||||
better ways to set this up than I've done! If you run across any
|
||||
problems, please post to the google-ctemplate Google Group, or report
|
||||
them on the google-ctemplate Google Code site:
|
||||
http://groups.google.com/group/google-ctemplate
|
||||
http://code.google.com/p/google-ctemplate/issues/list
|
||||
|
||||
-- craig
|
|
@ -94,12 +94,12 @@ the appropriate escaping modifiers after your own.</p>
|
|||
that use but allows you to indicate a different choice as shown
|
||||
below:
|
||||
|
||||
<p><table border=1 cellpadding=3>
|
||||
<table border="1" cellpadding="3" summary="Alternatives to modifiers">
|
||||
<tr><th>TemplateContext</th><th>Primary Modifier</th>
|
||||
<th>Accepted alternatives</th></tr>
|
||||
|
||||
<tr>
|
||||
<td><code>TC_HTML</code></code></td>
|
||||
<td><code>TC_HTML</code></td>
|
||||
<td><code>:html_escape</code></td>
|
||||
<td><ul>
|
||||
<li><code>:pre_escape</code></li>
|
||||
|
@ -108,6 +108,7 @@ the appropriate escaping modifiers after your own.</p>
|
|||
<li><code>:html_escape_with_arg=url</code></li>
|
||||
<li><code>:url_query_escape</code></li>
|
||||
<li><code>:url_escape_with_arg=html</code></li>
|
||||
<li><code>:img_src_url_escape_with_arg=html</code></li>
|
||||
</ul></td>
|
||||
</tr>
|
||||
|
||||
|
@ -116,6 +117,7 @@ the appropriate escaping modifiers after your own.</p>
|
|||
<td><code>:cleanse_css</code></td>
|
||||
<td><ul>
|
||||
<li><code>:url_escape_with_arg=css</code></li>
|
||||
<li><code>:img_src_url_escape_with_arg=css</code></li>
|
||||
</ul></td>
|
||||
</tr>
|
||||
|
||||
|
@ -125,7 +127,7 @@ the appropriate escaping modifiers after your own.</p>
|
|||
<td><ul>
|
||||
<li><code>:html_escape</code></li>
|
||||
<li><code>:html_escape_with_arg=attribute</code></li>
|
||||
</td></ul>
|
||||
</ul></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -133,10 +135,10 @@ the appropriate escaping modifiers after your own.</p>
|
|||
<td><code>:javascript_escape</code></td>
|
||||
<td><ul>
|
||||
<li><code>:json_escape</code></li>
|
||||
</td></ul>
|
||||
</ul></td>
|
||||
</tr>
|
||||
|
||||
</table></p></li>
|
||||
</table></li>
|
||||
|
||||
<li> To add additional escaping modifiers. The Template System will
|
||||
never remove escaping directives you explicitly specify. </li>
|
||||
|
@ -159,13 +161,13 @@ the semantics of the variable therefore we fail the template
|
|||
initialization. An error is logged indicating the cause of
|
||||
the failure.</p>
|
||||
|
||||
<table border=1 cellpadding=3>
|
||||
<tr bgcolor="RoyalBlue">
|
||||
<table border="1" cellpadding="3" summary="Contexts for using modifiers">
|
||||
<tr bgcolor="#4169E1">
|
||||
<th>Context</th><th>HTML Quoted?</th>
|
||||
<th>Examples</th><th>Action Performed</th>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>Regular HTML Body and HTML comments</td><td>Any</td>
|
||||
<td><pre><p>Hello {{USER}}</p>
|
||||
</pre></td>
|
||||
|
@ -173,95 +175,95 @@ the failure.</p>
|
|||
<code>:html_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In URL attribute: Starts at pos 0</td><td>Yes</td>
|
||||
<td><pre><img src="{{URL}}">;</pre></td>
|
||||
<td><pre><a href="{{URL}}">;</pre></td>
|
||||
<td>Escape <code>URL</code> using
|
||||
<code>:url_escape_with_arg=html</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In URL attribute: Other</td><td>Yes</td>
|
||||
<td><pre><a href="/foo?q={{QUERY}}"></pre></td>
|
||||
<td>Escape <code>QUERY</code> using
|
||||
<code>:html_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In URL attribute: Starting at pos 0</td><td>No</td>
|
||||
<td><pre><form action={{URL}}></pre></td>
|
||||
<td><em>Fail template initialization</em></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In URL attribute: Other</td><td>No</td>
|
||||
<td><pre><a href=/foo?q={{QUERY}}>My Link</a></pre></td>
|
||||
<td>Escape <code>QUERY</code> using
|
||||
<code>:url_query_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>In STYLE attribute</td><td>Yes</td>
|
||||
<td><pre><div style="color:{{COLOR}};"></pre></td>
|
||||
<td>Escape <code>COLOR</code> using
|
||||
<code>:cleanse_css</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>In STYLE attribute</td><td>No</td>
|
||||
<td><pre><div style=color:{{COLOR}};></pre></td>
|
||||
<td><em>Fail template initialization</em></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In Javascript attribute: String literal</td><td>Yes</td>
|
||||
<td><pre><a href="url" onclick="doFoo('{{ARG}}');"></pre></td>
|
||||
<td>Escape <code>ARG</code> using
|
||||
<code>:javascript_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In Javascript attribute: Non-string literal</td><td>Yes</td>
|
||||
<td><pre><a href="url" onclick="doFoo({{ARG}});"></pre></td>
|
||||
<td>Escape <code>ARG</code> using
|
||||
<code>:javascript_escape_with_arg=number</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In Javascript attribute: Any</td><td>No</td>
|
||||
<td><pre><a href="url" onclick=doFoo('{{ARG}}');></pre></td>
|
||||
<td><em>Fail template initialization.</em></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>In all other attributes</td><td>Yes</td>
|
||||
<td><pre><b class="{{CLASS}}"></pre></td>
|
||||
<td>Escape <code>CLASS</code> using
|
||||
<code>:html_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>In all other attributes</td><td>No</td>
|
||||
<td><pre><table border={{BORDER}}></pre></td>
|
||||
<td>Escape <code>BORDER</code> using
|
||||
<code>:html_escape_with_arg=attribute</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In Javascript code: In a string literal</td><td>Any</td>
|
||||
<td><pre><script>var a = '{{VALUE}}';</script></pre></td>
|
||||
<td>Escape <code>VALUE</code> using
|
||||
<code>:javascript_escape</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AntiqueWhite">
|
||||
<tr bgcolor="#FAEBD7">
|
||||
<td>In Javascript code: Non-string literal</td><td>Any</td>
|
||||
<td><pre><script>var a = {{VALUE}};</script></pre></td>
|
||||
<td>Escape <code>VALUE</code> using
|
||||
<code>:javascript_escape_with_arg=number</code></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="AliceBlue">
|
||||
<tr bgcolor="#F0F8FF">
|
||||
<td>In a <style> tag</td><td>Any</td>
|
||||
<td><pre><style>font-size={{FONTSIZE}};</style></pre></td>
|
||||
<td>Escape <code>FONTSIZE</code> using
|
||||
|
@ -270,7 +272,7 @@ the failure.</p>
|
|||
|
||||
</table>
|
||||
|
||||
<p><h4>Comments:</h4>
|
||||
<h4>Comments:</h4>
|
||||
<ul>
|
||||
<li>For values of URL-accepting attributes, we apply a different
|
||||
modifier if the variable is at the beginning of the attribute
|
||||
|
@ -357,7 +359,7 @@ restrictions governing the use of this template system.</p>
|
|||
Javascript (<code>TC_JS</code>) templates are well supported.
|
||||
Other template contexts have only basic support.
|
||||
For these contexts, variables are escaped as follows:</p>
|
||||
<table border=1 cellpadding=3>
|
||||
<table border="1" cellpadding="3" summary="HTML contexts for modifiers">
|
||||
<tr><th>TemplateContext</th><th>Escaping Applied</th></tr>
|
||||
<tr><td>TC_JSON</td>
|
||||
<td><code>:javascript_escape</code></td></tr>
|
||||
|
@ -406,7 +408,6 @@ it does not match the template type given, we log a warning.</p>
|
|||
|
||||
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<address>
|
||||
Jad Boutros<br>
|
||||
|
|
|
@ -99,7 +99,7 @@ call "expanding"), here's the output we would get:</p>
|
|||
It's boring</body></html>
|
||||
</pre>
|
||||
|
||||
<p><code>{{TITLE}}</code> and <code>{{{BODY}}</code> are <b>template
|
||||
<p><code>{{TITLE}}</code> and <code>{{BODY}}</code> are <b>template
|
||||
elements</b>, also called <b>markers</b>. In the dictionary,
|
||||
<code>TITLE</code>, <code>BODY</code>, and <code>DATE</code> are
|
||||
<b>dictionary names</b>, and the values associated with each one, such
|
||||
|
@ -728,7 +728,7 @@ as if it were a template file, and inserts it into the global cache
|
|||
with the key and strip-mode that you provide. You can then use this
|
||||
key and strip-mode as the first two arguments to
|
||||
<code>ExpandTemplate</code>. You can also use the key as the argument
|
||||
to <code>ctemplate::TemplateDictionary::SetFilename()<code>.</p>
|
||||
to <code>ctemplate::TemplateDictionary::SetFilename()</code>.</p>
|
||||
|
||||
<p>Prefer file-based to string-based templates where possible.
|
||||
Updating a file-based template requires merely a data push, rather
|
||||
|
|
|
@ -68,8 +68,7 @@ templates.</p>
|
|||
option is set, which puts template code in namespace
|
||||
<code>ctemplate</code>.)</p>
|
||||
|
||||
|
||||
<h2> <A NAME="template">Expanding Templates </h2>
|
||||
<h2> <A NAME="template">Expanding Templates</A> </h2>
|
||||
|
||||
|
||||
<h3> The Template Language </h3>
|
||||
|
@ -526,8 +525,8 @@ code:
|
|||
ctemplate::TemplateDictionary::SetGlobalValue("NAME", "John Doe");
|
||||
ctemplate::TemplateDictionary dict_c("set_value_demo, part 2");
|
||||
|
||||
ctemplate::ExpandTemplate("A.tpl", ..., &dict);
|
||||
ctemplate::ExpandTemplate("C.tpl", ..., &dict_c);
|
||||
ctemplate::ExpandTemplate("A.tpl", ..., &dict);
|
||||
ctemplate::ExpandTemplate("C.tpl", ..., &dict_c);
|
||||
</pre>
|
||||
|
||||
<p>The first expand yields this:</p>
|
||||
|
@ -996,19 +995,69 @@ sign:</p>
|
|||
<p>Here are the modifiers that are built in to the template system.
|
||||
They are all defined in template_modifiers.cc:</p>
|
||||
|
||||
<table border=1 cellpadding=3>
|
||||
<table border="1" cellpadding="3" summary="List of built-in modifiers">
|
||||
<tr><th>long name</th><th>short name</th><th>description</th></tr>
|
||||
|
||||
<tr><td><code>:cleanse_css</code></td><td><code>:c</code></td>
|
||||
<td>Removes characters not safe for a CSS value. Safe characters
|
||||
are alphanumeric, space, underscore, period, coma, exclamation
|
||||
mark, pound, percent, and dash.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:html_escape</code></td><td><code>:h</code></td>
|
||||
<td>html-escapes the variable before output
|
||||
(eg <code>&</code> -> <code>&amp;</code>)</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:html_escape_with_arg</code></td><td><code>:H</code></td>
|
||||
<td>special purpose html escaping. See
|
||||
<a href="#html_escape_args">:H Arguments</a>
|
||||
below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:img_src_url_escape_with_arg</code></td><td><code>:I</code></td>
|
||||
<td>special purpose image url escaping. See
|
||||
<a href="#url_escape_args">:I and :U Arguments</a>
|
||||
below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:javascript_escape</code></td><td><code>:j</code></td>
|
||||
<td>javascript-escapes the variable before output (eg
|
||||
<code>"</code> -> <code>\x27</code> and
|
||||
<code>&</code> -> <code>\x26</code>)</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:javascript_escape_with_arg</code></td><td><code>:J</code>
|
||||
</td>
|
||||
<td>special purpose javascript escaping. See
|
||||
<a href="#javascript_escape_args">:J Arguments</a>
|
||||
below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:json_escape</code></td><td><code>:o</code></td>
|
||||
<td>json-escapes a variable before output as a string in json;
|
||||
HTML characters are escaped using Unicode escape sequences
|
||||
(e.g <code>&</code> -> <code>\u0026</code>) to comply with
|
||||
<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:none</code></td><td></td>
|
||||
<td>leaves the variable as is (used to disable <A
|
||||
HREF="#auto_escape">auto-escaping</A>)</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:pre_escape</code></td><td><code>:p</code></td>
|
||||
<td>pre-escapes the variable before output (same as html_escape but
|
||||
whitespace is preserved; useful for <pre>...</pre>)</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:url_escape_with_arg</code></td><td><code>:U</code></td>
|
||||
<td>special purpose url escaping. See
|
||||
<a href="#url_escape_args">:I and :U Arguments</a>
|
||||
below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:url_query_escape</code></td><td><code>:u</code></td>
|
||||
<td>performs URL escaping on the variable before output.
|
||||
space is turned into +, and everything other than [0-9a-zA-Z.,_:*/~!()-], is
|
||||
|
@ -1018,39 +1067,6 @@ They are all defined in template_modifiers.cc:</p>
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:javascript_escape</code></td><td><code>:j</code></td>
|
||||
<td>javascript-escapes the variable before output (eg
|
||||
<code>"</code> -> <code>\x27</code> and
|
||||
<code>&</code> -> <code>\x26</code>)</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:javascript_escape_with_arg</code></td><td><code>:J</code>
|
||||
</td>
|
||||
<td>special purpose javascript escaping. See below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:cleanse_css</code></td><td><code>:c</code></td>
|
||||
<td>Removes characters not safe for a CSS value. Safe characters
|
||||
are alphanumeric, space, underscore, period, coma, exclamation
|
||||
mark, pound, percent, and dash.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:json_escape</code></td><td><code>:o</code></td>
|
||||
<td>json-escapes a variable before output as a string in json;
|
||||
HTML characters are escaped using Unicode escape sequences
|
||||
(e.g <code>&</code> -> <code>\u0026</code>) to comply with
|
||||
<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:html_escape_with_arg</code></td><td><code>:H</code></td>
|
||||
<td>special purpose html escaping. See below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:url_escape_with_arg</code></td><td><code>:U</code></td>
|
||||
<td>special purpose url escaping. See below for details.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:xml_escape</code></td><td></td>
|
||||
<td>xml-escapes the variable before output
|
||||
(the five characters <code><>&"'</code> become
|
||||
|
@ -1059,19 +1075,16 @@ They are all defined in template_modifiers.cc:</p>
|
|||
for escaping content within CDATA blocks.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>:none</code></td><td></td>
|
||||
<td>leaves the variable as is (used to disable <A
|
||||
HREF="#auto_escape">auto-escaping</A>)</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<p>The <code>*_with_arg</code> modifiers require an argument to
|
||||
specify the type of escaping to use.
|
||||
specify the type of escaping to use. The following sections list
|
||||
the supported arguments for each of these modifiers.
|
||||
|
||||
<h4 id="html_escape_args">:H Arguments</h4>
|
||||
<p>Here are the values that are supported by
|
||||
the <code>html_escape_with_arg</code> modifier:</p>
|
||||
<table border=1 cellpadding=3>
|
||||
<table border="1" cellpadding="3" summary="Arguments for :H modifier">
|
||||
<tr><th>value</th><th>description</th></tr>
|
||||
|
||||
<tr><td><code>=snippet</code></td>
|
||||
|
@ -1097,16 +1110,33 @@ the <code>html_escape_with_arg</code> modifier:</p>
|
|||
|
||||
</table>
|
||||
|
||||
<h4 id="url_escape_args">:I and :U Arguments</h4>
|
||||
<p>Here are the values that are supported by
|
||||
the <code>url_escape_with_arg</code> modifier:</p>
|
||||
<table border=1 cellpadding=3>
|
||||
the <code>img_src_url_escape_with_arg</code> and
|
||||
<code>url_escape_with_arg</code> modifiers:</p>
|
||||
<table border="1" cellpadding="3" summary="Arguments for :I and :U modifiers">
|
||||
<tr><th>value</th><th>description</th></tr>
|
||||
|
||||
<tr><td><code>=html</code></td>
|
||||
<td>Ensures that a variable contains a safe URL. Safe means that
|
||||
it is either a http or https URL, or else it has no protocol
|
||||
specified. If the URL is safe it is html-escaped, otherwise
|
||||
it is replaced with <code>#</code>.</td>
|
||||
specified.
|
||||
<ul>
|
||||
<li>If the URL is safe, the modifier HTML-escapes the URL.
|
||||
<li>Otherwise, the modifier replaces the unsafe URL with one of the
|
||||
following values:
|
||||
<ul>
|
||||
<li><code>/images/cleardot.gif</code> (the <code>:I</code>
|
||||
modifier)
|
||||
<li><code>#</code> (the <code>:U</code> modifier)
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<b>Do not use <code>:U</code> for image URLs.</b> Use <code>:I</code>
|
||||
instead. <code>#</code> is not a safe replacement for an image URL.
|
||||
<code><img src=#></code> can cause each browser to request the
|
||||
entire page again.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><code>=javascript</code></td>
|
||||
|
@ -1123,14 +1153,16 @@ the <code>url_escape_with_arg</code> modifier:</p>
|
|||
</tr>
|
||||
|
||||
<tr><td><code>=query</code></td>
|
||||
<td>Same as <code>url_query_escape</code>.</td>
|
||||
<td>(Supported for <code>:U</code> only) Same as
|
||||
<code>url_query_escape</code>.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h4 id="javascript_escape_args">:J Arguments</h4>
|
||||
<p>Here are the values that are supported by
|
||||
the <code>javascript_escape_with_arg</code> modifier:</p>
|
||||
<table border=1 cellpadding=3>
|
||||
<table border="1" cellpadding="3" summary="Arguments for :J modifier">
|
||||
<tr><th>value</th><th>description</th></tr>
|
||||
|
||||
<tr><td><code>=number</code></td>
|
||||
|
@ -1149,12 +1181,6 @@ the <code>javascript_escape_with_arg</code> modifier:</p>
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<p><strong>NOTE:</strong> At the moment, there are no filters for
|
||||
handling XML attributes and text nodes. For HTML snippets, use the
|
||||
html filter; in other situations, it may be appropriate to use CDATA
|
||||
blocks.</p>
|
||||
|
||||
|
||||
<h3> Custom Modifiers </h3>
|
||||
|
||||
<p>In addition to the built-in modifiers, you can write your own
|
||||
|
@ -1480,7 +1506,7 @@ workflow: the common template use-case would be:</p>
|
|||
<pre>
|
||||
Template* tpl = Template::GetTemplate(filename, strip_mode);
|
||||
TemplateDictionary dict(name);
|
||||
tpl->Expand(&dict, &outstring);
|
||||
tpl->Expand(&dict, &outstring);
|
||||
</pre>
|
||||
|
||||
<p>In current use, this model is deprecated in favor of the single
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Source: ctemplate
|
||||
Section: libdevel
|
||||
Priority: optional
|
||||
Maintainer: Google Inc. <opensource@google.com>
|
||||
Maintainer: Google Inc. <google-ctemplate@googlegroups.com>
|
||||
Build-Depends: debhelper (>= 4.0.0)
|
||||
Standards-Version: 3.6.1
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Group: Development/Libraries
|
|||
URL: http://code.google.com/p/google-ctemplate
|
||||
License: BSD
|
||||
Vendor: Google
|
||||
Packager: Google Inc. <opensource@google.com>
|
||||
Packager: Google Inc. <google-ctemplate@googlegroups.com>
|
||||
Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
|
||||
Distribution: Redhat 7 and above.
|
||||
Buildroot: %{_tmppath}/%{name}-root
|
||||
|
|
|
@ -60,7 +60,10 @@ class @ac_windows_dllexport@ PerExpandData {
|
|||
PerExpandData()
|
||||
: annotate_path_(NULL),
|
||||
annotator_(NULL),
|
||||
expand_modifier_(NULL) { }
|
||||
expand_modifier_(NULL),
|
||||
map_(NULL) { }
|
||||
|
||||
~PerExpandData();
|
||||
|
||||
// Indicate that annotations should be inserted during template expansion.
|
||||
// template_path_start - the start of a template path. When
|
||||
|
@ -110,16 +113,11 @@ class @ac_windows_dllexport@ PerExpandData {
|
|||
// (see template_modifiers.h). Call with value set to NULL to clear
|
||||
// any value previously set. Caller is responsible for ensuring key
|
||||
// and value point to valid data for the lifetime of this object.
|
||||
void InsertForModifiers(const char* key, const void* value) {
|
||||
map_[key] = value;
|
||||
}
|
||||
void InsertForModifiers(const char* key, const void* value);
|
||||
|
||||
// Retrieve data specific to this Expand call. Returns NULL if key
|
||||
// is not found. This should only be used by template modifiers.
|
||||
const void* LookupForModifiers(const char* key) const {
|
||||
const DataMap::const_iterator it = map_.find(key);
|
||||
return it == map_.end() ? NULL : it->second;
|
||||
}
|
||||
const void* LookupForModifiers(const char* key) const;
|
||||
|
||||
// Same as Lookup, but casts the result to a c string.
|
||||
const char* LookupForModifiersAsString(const char* key) const {
|
||||
|
@ -140,7 +138,7 @@ class @ac_windows_dllexport@ PerExpandData {
|
|||
const char* annotate_path_;
|
||||
TemplateAnnotator* annotator_;
|
||||
const TemplateModifier* expand_modifier_;
|
||||
DataMap map_;
|
||||
DataMap* map_;
|
||||
|
||||
PerExpandData(const PerExpandData&); // disallow evil copy constructor
|
||||
void operator=(const PerExpandData&); // disallow evil operator=
|
||||
|
|
|
@ -400,7 +400,7 @@ class @ac_windows_dllexport@ Template {
|
|||
|
||||
// Template markers have the form {{VARIABLE}}, etc. These constants
|
||||
// define the {{ and }} that delimit template markers.
|
||||
struct MarkerDelimiters {
|
||||
struct @ac_windows_dllexport@ MarkerDelimiters {
|
||||
const char* start_marker;
|
||||
size_t start_marker_len;
|
||||
const char* end_marker;
|
||||
|
@ -415,7 +415,7 @@ class @ac_windows_dllexport@ Template {
|
|||
};
|
||||
|
||||
// The current parsing state. Used in BuildTree() and subroutines
|
||||
struct ParseState {
|
||||
struct @ac_windows_dllexport@ ParseState {
|
||||
const char* bufstart;
|
||||
const char* bufend;
|
||||
enum { PS_UNUSED, GETTING_TEXT, GETTING_NAME } phase;
|
||||
|
|
|
@ -182,18 +182,31 @@ extern @ac_windows_dllexport@ CleanseCss cleanse_css;
|
|||
// url that doesn't have a protocol hidden in it (ie [foo.html] is
|
||||
// fine, but not [javascript:foo]) and then performs another type of
|
||||
// escaping. Returns the url escaped with the specified modifier if
|
||||
// good, otherwise returns "#".
|
||||
// good, otherwise returns a safe replacement URL.
|
||||
// This is normally "#", but for <img> tags, it is not safe to set
|
||||
// the src attribute to "#". This is because this causes some browsers
|
||||
// to reload the page, which can cause a DoS.
|
||||
class @ac_windows_dllexport@ ValidateUrl : public TemplateModifier {
|
||||
public:
|
||||
explicit ValidateUrl(const TemplateModifier& chained_modifier)
|
||||
: chained_modifier_(chained_modifier) { }
|
||||
explicit ValidateUrl(const TemplateModifier& chained_modifier,
|
||||
const char* unsafe_url_replacement)
|
||||
: chained_modifier_(chained_modifier),
|
||||
unsafe_url_replacement_(unsafe_url_replacement),
|
||||
unsafe_url_replacement_length_(strlen(unsafe_url_replacement)) { }
|
||||
MODIFY_SIGNATURE_;
|
||||
static const char* const kUnsafeUrlReplacement;
|
||||
static const char* const kUnsafeImgSrcUrlReplacement;
|
||||
private:
|
||||
const TemplateModifier& chained_modifier_;
|
||||
const char* unsafe_url_replacement_;
|
||||
int unsafe_url_replacement_length_;
|
||||
};
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_url_and_html_escape;
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_url_and_javascript_escape;
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_url_and_css_escape;
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_img_src_url_and_html_escape;
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_img_src_url_and_javascript_escape;
|
||||
extern @ac_windows_dllexport@ ValidateUrl validate_img_src_url_and_css_escape;
|
||||
|
||||
// Escapes < > & " ' to < > & " ' (same as in HtmlEscape).
|
||||
// If you use it within a CDATA section, you may be escaping more characters
|
||||
|
|
|
@ -124,12 +124,12 @@ static void Version(FILE* outfile) {
|
|||
|
||||
// Removes all non alphanumeric characters from a string to form a
|
||||
// valid C identifier to use as a double-inclusion guard.
|
||||
static void ConvertToIdentifier(string& s) {
|
||||
for (string::size_type i = 0; i < s.size(); i++) {
|
||||
if (!isalnum(s[i]))
|
||||
s[i] = '_';
|
||||
static void ConvertToIdentifier(string* s) {
|
||||
for (string::size_type i = 0; i < s->size(); i++) {
|
||||
if (!isalnum((*s)[i]))
|
||||
(*s)[i] = '_';
|
||||
else
|
||||
s[i] = toupper(s[i]);
|
||||
(*s)[i] = toupper((*s)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ int main(int argc, char **argv) {
|
|||
"//\n");
|
||||
|
||||
string guard(string("TPL_") + header_file);
|
||||
ConvertToIdentifier(guard);
|
||||
ConvertToIdentifier(&guard);
|
||||
guard.append("_H_");
|
||||
|
||||
contents.append(string("#ifndef ") + guard + "\n");
|
||||
|
|
|
@ -49,6 +49,10 @@ bool PerExpandData::DataEq::operator()(const char* s1, const char* s2) const {
|
|||
}
|
||||
#endif
|
||||
|
||||
PerExpandData::~PerExpandData() {
|
||||
delete map_;
|
||||
}
|
||||
|
||||
TemplateAnnotator* PerExpandData::annotator() const {
|
||||
if (annotator_ != NULL) {
|
||||
return annotator_;
|
||||
|
@ -59,4 +63,19 @@ TemplateAnnotator* PerExpandData::annotator() const {
|
|||
return &g_default_annotator;
|
||||
}
|
||||
|
||||
void PerExpandData::InsertForModifiers(const char* key, const void* value) {
|
||||
if (!map_)
|
||||
map_ = new DataMap;
|
||||
(*map_)[key] = value;
|
||||
}
|
||||
|
||||
// Retrieve data specific to this Expand call. Returns NULL if key
|
||||
// is not found. This should only be used by template modifiers.
|
||||
const void* PerExpandData::LookupForModifiers(const char* key) const {
|
||||
if (!map_)
|
||||
return NULL;
|
||||
const DataMap::const_iterator it = map_->find(key);
|
||||
return it == map_->end() ? NULL : it->second;
|
||||
}
|
||||
|
||||
} // namespace ctemplate
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h> // for fwrite, fflush
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -97,6 +97,15 @@ using HTMLPARSER_NAMESPACE::HtmlParser;
|
|||
|
||||
#define arraysize(x) ( sizeof(x) / sizeof(*(x)) )
|
||||
|
||||
// TODO(csilvers): use our own tables for these?
|
||||
static bool ascii_isalnum(char c) {
|
||||
return ((c & 0x80) == 0) && isalnum(c); // 7-bit ascii, and an alnum
|
||||
}
|
||||
|
||||
static bool ascii_isspace(char c) {
|
||||
return ((c & 0x80) == 0) && isspace(c); // 7-bit ascii, and a space
|
||||
}
|
||||
|
||||
TemplateId GlobalIdForSTS_INIT(const TemplateString& s) {
|
||||
return s.GetGlobalId(); // normally this method is private
|
||||
}
|
||||
|
@ -1779,7 +1788,7 @@ bool SectionTemplateNode::AddSubnode(Template *my_template) {
|
|||
// nothing else.
|
||||
static bool IsValidName(const char* name, int namelen) {
|
||||
for (const char *cur_char = name; cur_char - name < namelen; ++cur_char) {
|
||||
if (!isalnum(*cur_char) && *cur_char != '_')
|
||||
if (!ascii_isalnum(*cur_char) && *cur_char != '_')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -2386,12 +2395,12 @@ bool Template::ParseDelimiters(const char* text, size_t textlen,
|
|||
// so we can take a size_t instead of an int. The code is simple enough.
|
||||
static void StripTemplateWhiteSpace(const char** str, size_t* len) {
|
||||
// Strip off trailing whitespace.
|
||||
while ((*len) > 0 && isspace((*str)[(*len)-1])) {
|
||||
while ((*len) > 0 && ascii_isspace((*str)[(*len)-1])) {
|
||||
(*len)--;
|
||||
}
|
||||
|
||||
// Strip off leading whitespace.
|
||||
while ((*len) > 0 && isspace((*str)[0])) {
|
||||
while ((*len) > 0 && ascii_isspace((*str)[0])) {
|
||||
(*len)--;
|
||||
(*str)++;
|
||||
}
|
||||
|
|
|
@ -339,6 +339,11 @@ void CssUrlEscape::Modify(const char* in, size_t inlen,
|
|||
}
|
||||
CssUrlEscape css_url_escape;
|
||||
|
||||
// These URLs replace unsafe URLs for :U and :I url-escaping modes.
|
||||
const char* const ValidateUrl::kUnsafeUrlReplacement = "#";
|
||||
const char* const ValidateUrl::kUnsafeImgSrcUrlReplacement =
|
||||
"/images/cleardot.gif";
|
||||
|
||||
void ValidateUrl::Modify(const char* in, size_t inlen,
|
||||
const PerExpandData* per_expand_data,
|
||||
ExpandEmitter* out, const string& arg) const {
|
||||
|
@ -359,16 +364,35 @@ void ValidateUrl::Modify(const char* in, size_t inlen,
|
|||
// and ftp
|
||||
} else {
|
||||
// It's a bad protocol, so return something safe
|
||||
chained_modifier_.Modify("#", 1, per_expand_data, out, "");
|
||||
chained_modifier_.Modify(unsafe_url_replacement_,
|
||||
unsafe_url_replacement_length_,
|
||||
per_expand_data,
|
||||
out,
|
||||
"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If we get here, it's a valid url, so just escape it
|
||||
chained_modifier_.Modify(in, inlen, per_expand_data, out, "");
|
||||
}
|
||||
ValidateUrl validate_url_and_html_escape(html_escape);
|
||||
ValidateUrl validate_url_and_javascript_escape(javascript_escape);
|
||||
ValidateUrl validate_url_and_css_escape(css_url_escape);
|
||||
ValidateUrl validate_url_and_html_escape(
|
||||
html_escape,
|
||||
ValidateUrl::kUnsafeUrlReplacement);
|
||||
ValidateUrl validate_url_and_javascript_escape(
|
||||
javascript_escape,
|
||||
ValidateUrl::kUnsafeUrlReplacement);
|
||||
ValidateUrl validate_url_and_css_escape(
|
||||
css_url_escape,
|
||||
ValidateUrl::kUnsafeUrlReplacement);
|
||||
ValidateUrl validate_img_src_url_and_html_escape(
|
||||
html_escape,
|
||||
ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ValidateUrl validate_img_src_url_and_javascript_escape(
|
||||
javascript_escape,
|
||||
ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ValidateUrl validate_img_src_url_and_css_escape(
|
||||
css_url_escape,
|
||||
ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
|
||||
void XmlEscape::Modify(const char* in, size_t inlen,
|
||||
const PerExpandData*,
|
||||
|
@ -675,7 +699,9 @@ static struct ModifierWithAlternatives {
|
|||
} g_modifiers[] = {
|
||||
/* 0 */ { ModifierInfo("cleanse_css", 'c',
|
||||
XSS_WEB_STANDARD, &cleanse_css),
|
||||
{&g_modifiers[16].modifier_info} }, // url_escape_with_arg=css
|
||||
{&g_modifiers[16].modifier_info, // url_escape_with_arg=css
|
||||
// img_src_url_escape_with_arg=css
|
||||
&g_modifiers[19].modifier_info} },
|
||||
/* 1 */ { ModifierInfo("html_escape", 'h',
|
||||
XSS_WEB_STANDARD, &html_escape),
|
||||
{&g_modifiers[2].modifier_info, // html_escape_with_arg=snippet
|
||||
|
@ -685,7 +711,9 @@ static struct ModifierWithAlternatives {
|
|||
&g_modifiers[8].modifier_info, // pre_escape
|
||||
&g_modifiers[9].modifier_info, // url_query_escape
|
||||
&g_modifiers[11].modifier_info, // url_escape_with_arg=html
|
||||
&g_modifiers[12].modifier_info} }, // url_escape_with_arg=query
|
||||
&g_modifiers[12].modifier_info, // url_escape_with_arg=query
|
||||
// img_src_url_escape_with_arg=html
|
||||
&g_modifiers[18].modifier_info} },
|
||||
|
||||
/* 2 */ { ModifierInfo("html_escape_with_arg=snippet", 'H',
|
||||
XSS_WEB_STANDARD, &snippet_escape),
|
||||
|
@ -736,6 +764,15 @@ static struct ModifierWithAlternatives {
|
|||
XSS_WEB_STANDARD, &javascript_number), {} },
|
||||
/* 16 */ { ModifierInfo("url_escape_with_arg=css", 'U',
|
||||
XSS_WEB_STANDARD, &validate_url_and_css_escape), {} },
|
||||
/* 17 */ { ModifierInfo("img_src_url_escape_with_arg=javascript", 'I',
|
||||
XSS_WEB_STANDARD,
|
||||
&validate_img_src_url_and_javascript_escape), {} },
|
||||
/* 18 */ { ModifierInfo("img_src_url_escape_with_arg=html", 'I',
|
||||
XSS_WEB_STANDARD,
|
||||
&validate_img_src_url_and_html_escape), {} },
|
||||
/* 19 */ { ModifierInfo("img_src_url_escape_with_arg=css", 'I',
|
||||
XSS_WEB_STANDARD,
|
||||
&validate_img_src_url_and_css_escape), {} },
|
||||
};
|
||||
|
||||
static vector<const ModifierInfo*> g_extension_modifiers;
|
||||
|
|
|
@ -876,6 +876,7 @@ class TemplateCacheUnittest {
|
|||
AssertExpandIs(cache_tpl1, &dict, "{valid template}", true);
|
||||
const Template* cache_tpl2 = cache.GetTemplate(filename2, DO_NOT_STRIP);
|
||||
assert(cache_tpl2);
|
||||
static_cast<void>(cache_tpl2); // avoid unused var warning in opt mode
|
||||
AssertExpandWithCacheIs(&cache, filename2, DO_NOT_STRIP, &dict, NULL,
|
||||
"hi bar\n", true);
|
||||
|
||||
|
@ -892,6 +893,7 @@ class TemplateCacheUnittest {
|
|||
string filename3 = StringToTemplateFile("{yet another valid template}");
|
||||
const Template* cache_tpl3 = cache.GetTemplate(filename3, STRIP_WHITESPACE);
|
||||
assert(!cache_tpl3);
|
||||
static_cast<void>(cache_tpl3); // avoid unused var warning in opt mode
|
||||
|
||||
// 2. Reloading existing templates fails.
|
||||
StringToFile("{file1 contents changed}", filename1);
|
||||
|
|
|
@ -230,9 +230,49 @@ class TemplateModifiersUnittest {
|
|||
ASSERT_STREQ(peer.GetSectionValue("harder https URL"),
|
||||
"https://www.google.com/search?q=f&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy javascript URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder javascript URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy relative URL"),
|
||||
"foobar.html");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder relative URL"),
|
||||
"/search?q=green flowers&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("ftp URL"),
|
||||
"ftp://ftp.example.org/pub/file.txt");
|
||||
}
|
||||
|
||||
static void TestValidateImgSrcUrlHtmlEscape() {
|
||||
TemplateDictionary dict("TestValidateImgSrcUrlHtmlEscape", NULL);
|
||||
dict.SetEscapedValue("easy http URL", "http://www.google.com",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("harder https URL",
|
||||
"https://www.google.com/search?q=f&hl=en",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("easy javascript URL",
|
||||
"javascript:alert(document.cookie)",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("harder javascript URL",
|
||||
"javascript:alert(10/5)",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("easy relative URL",
|
||||
"foobar.html",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("harder relative URL",
|
||||
"/search?q=green flowers&hl=en",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
dict.SetEscapedValue("ftp URL",
|
||||
"ftp://ftp.example.org/pub/file.txt",
|
||||
ctemplate::validate_img_src_url_and_html_escape);
|
||||
|
||||
TemplateDictionaryPeer peer(&dict); // peer can look inside the dict
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy http URL"),
|
||||
"http://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder https URL"),
|
||||
"https://www.google.com/search?q=f&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy relative URL"),
|
||||
"foobar.html");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder relative URL"),
|
||||
|
@ -290,20 +330,84 @@ class TemplateModifiersUnittest {
|
|||
"https://www.google.com/search?q\\x3df\\x26hl\\x3den");
|
||||
ASSERT_STREQ(peer.GetSectionValue("mangled http URL"),
|
||||
"HTTP://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy javascript URL"),
|
||||
"#");
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy javascript URL"), "#");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder javascript URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy relative URL"),
|
||||
"foobar.html");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder relative URL"),
|
||||
"/search?q\\x3dgreen flowers\\x26hl\\x3den");
|
||||
ASSERT_STREQ(peer.GetSectionValue("data URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("mangled javascript URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder mangled javascript URL"),
|
||||
"#");
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
}
|
||||
|
||||
static void TestValidateImgSrcUrlJavascriptEscape() {
|
||||
TemplateDictionary dict("TestValidateImgSrcUrlJavascriptEscape", NULL);
|
||||
dict.SetEscapedValue(
|
||||
"easy http URL", "http://www.google.com",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"harder https URL",
|
||||
"https://www.google.com/search?q=f&hl=en",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"mangled http URL", "HTTP://www.google.com",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"easy javascript URL",
|
||||
"javascript:alert(document.cookie)",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"harder javascript URL",
|
||||
"javascript:alert(10/5)",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"easy relative URL",
|
||||
"foobar.html",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"harder relative URL",
|
||||
"/search?q=green flowers&hl=en",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"data URL",
|
||||
"data: text/html",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"mangled javascript URL",
|
||||
"javaSCRIPT:alert(5)",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
dict.SetEscapedValue(
|
||||
"harder mangled javascript URL",
|
||||
"java\nSCRIPT:alert(5)",
|
||||
ctemplate::validate_img_src_url_and_javascript_escape);
|
||||
|
||||
|
||||
TemplateDictionaryPeer peer(&dict); // peer can look inside the dict
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy http URL"),
|
||||
"http://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder https URL"),
|
||||
"https://www.google.com/search?q\\x3df\\x26hl\\x3den");
|
||||
ASSERT_STREQ(peer.GetSectionValue("mangled http URL"),
|
||||
"HTTP://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy relative URL"),
|
||||
"foobar.html");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder relative URL"),
|
||||
"/search?q\\x3dgreen flowers\\x26hl\\x3den");
|
||||
ASSERT_STREQ(peer.GetSectionValue("data URL"),
|
||||
"/images/cleardot.gif");
|
||||
ASSERT_STREQ(peer.GetSectionValue("mangled javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder mangled javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
}
|
||||
|
||||
static void TestValidateUrlCssEscape() {
|
||||
|
@ -327,7 +431,38 @@ class TemplateModifiersUnittest {
|
|||
"http://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder https URL"),
|
||||
"https://www.google.com/search?q=f&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("javascript URL"), "#");
|
||||
ASSERT_STREQ(peer.GetSectionValue("javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("relative URL"),
|
||||
"/search?q=green flowers&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("hardest URL"),
|
||||
"http://www.google.com/s?q=%27bla%27"
|
||||
"&a=%22%22&b=%28%3Ctag%3E%29&c=%2A%0D%0A%5C%5Cbla");
|
||||
}
|
||||
|
||||
static void TestValidateImgSrcUrlCssEscape() {
|
||||
TemplateDictionary dict("TestValidateImgSrcUrlCssEscape", NULL);
|
||||
dict.SetEscapedValue("easy http URL", "http://www.google.com",
|
||||
ctemplate::validate_img_src_url_and_css_escape);
|
||||
dict.SetEscapedValue("harder https URL",
|
||||
"https://www.google.com/search?q=f&hl=en",
|
||||
ctemplate::validate_img_src_url_and_css_escape);
|
||||
dict.SetEscapedValue("javascript URL",
|
||||
"javascript:alert(document.cookie)",
|
||||
ctemplate::validate_img_src_url_and_css_escape);
|
||||
dict.SetEscapedValue("relative URL", "/search?q=green flowers&hl=en",
|
||||
ctemplate::validate_img_src_url_and_css_escape);
|
||||
dict.SetEscapedValue("hardest URL", "http://www.google.com/s?q='bla'"
|
||||
"&a=\"\"&b=(<tag>)&c=*\r\n\\\\bla",
|
||||
ctemplate::validate_img_src_url_and_css_escape);
|
||||
|
||||
TemplateDictionaryPeer peer(&dict); // peer can look inside the dict
|
||||
ASSERT_STREQ(peer.GetSectionValue("easy http URL"),
|
||||
"http://www.google.com");
|
||||
ASSERT_STREQ(peer.GetSectionValue("harder https URL"),
|
||||
"https://www.google.com/search?q=f&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("javascript URL"),
|
||||
ctemplate::ValidateUrl::kUnsafeImgSrcUrlReplacement);
|
||||
ASSERT_STREQ(peer.GetSectionValue("relative URL"),
|
||||
"/search?q=green flowers&hl=en");
|
||||
ASSERT_STREQ(peer.GetSectionValue("hardest URL"),
|
||||
|
@ -900,8 +1035,11 @@ int main(int argc, char** argv) {
|
|||
TemplateModifiersUnittest::TestPreEscape();
|
||||
TemplateModifiersUnittest::TestXmlEscape();
|
||||
TemplateModifiersUnittest::TestValidateUrlHtmlEscape();
|
||||
TemplateModifiersUnittest::TestValidateImgSrcUrlHtmlEscape();
|
||||
TemplateModifiersUnittest::TestValidateUrlJavascriptEscape();
|
||||
TemplateModifiersUnittest::TestValidateImgSrcUrlJavascriptEscape();
|
||||
TemplateModifiersUnittest::TestValidateUrlCssEscape();
|
||||
TemplateModifiersUnittest::TestValidateImgSrcUrlCssEscape();
|
||||
TemplateModifiersUnittest::TestCleanseAttribute();
|
||||
TemplateModifiersUnittest::TestCleanseCss();
|
||||
TemplateModifiersUnittest::TestJavascriptEscape();
|
||||
|
|
|
@ -65,7 +65,10 @@ class CTEMPLATE_DLL_DECL PerExpandData {
|
|||
PerExpandData()
|
||||
: annotate_path_(NULL),
|
||||
annotator_(NULL),
|
||||
expand_modifier_(NULL) { }
|
||||
expand_modifier_(NULL),
|
||||
map_(NULL) { }
|
||||
|
||||
~PerExpandData();
|
||||
|
||||
// Indicate that annotations should be inserted during template expansion.
|
||||
// template_path_start - the start of a template path. When
|
||||
|
@ -115,16 +118,11 @@ class CTEMPLATE_DLL_DECL PerExpandData {
|
|||
// (see template_modifiers.h). Call with value set to NULL to clear
|
||||
// any value previously set. Caller is responsible for ensuring key
|
||||
// and value point to valid data for the lifetime of this object.
|
||||
void InsertForModifiers(const char* key, const void* value) {
|
||||
map_[key] = value;
|
||||
}
|
||||
void InsertForModifiers(const char* key, const void* value);
|
||||
|
||||
// Retrieve data specific to this Expand call. Returns NULL if key
|
||||
// is not found. This should only be used by template modifiers.
|
||||
const void* LookupForModifiers(const char* key) const {
|
||||
const DataMap::const_iterator it = map_.find(key);
|
||||
return it == map_.end() ? NULL : it->second;
|
||||
}
|
||||
const void* LookupForModifiers(const char* key) const;
|
||||
|
||||
// Same as Lookup, but casts the result to a c string.
|
||||
const char* LookupForModifiersAsString(const char* key) const {
|
||||
|
@ -145,7 +143,7 @@ class CTEMPLATE_DLL_DECL PerExpandData {
|
|||
const char* annotate_path_;
|
||||
TemplateAnnotator* annotator_;
|
||||
const TemplateModifier* expand_modifier_;
|
||||
DataMap map_;
|
||||
DataMap* map_;
|
||||
|
||||
PerExpandData(const PerExpandData&); // disallow evil copy constructor
|
||||
void operator=(const PerExpandData&); // disallow evil operator=
|
||||
|
|
|
@ -405,7 +405,7 @@ class CTEMPLATE_DLL_DECL Template {
|
|||
|
||||
// Template markers have the form {{VARIABLE}}, etc. These constants
|
||||
// define the {{ and }} that delimit template markers.
|
||||
struct MarkerDelimiters {
|
||||
struct CTEMPLATE_DLL_DECL MarkerDelimiters {
|
||||
const char* start_marker;
|
||||
size_t start_marker_len;
|
||||
const char* end_marker;
|
||||
|
@ -420,7 +420,7 @@ class CTEMPLATE_DLL_DECL Template {
|
|||
};
|
||||
|
||||
// The current parsing state. Used in BuildTree() and subroutines
|
||||
struct ParseState {
|
||||
struct CTEMPLATE_DLL_DECL ParseState {
|
||||
const char* bufstart;
|
||||
const char* bufend;
|
||||
enum { PS_UNUSED, GETTING_TEXT, GETTING_NAME } phase;
|
||||
|
|
|
@ -53,6 +53,11 @@ struct stat;
|
|||
// as a compiler flag in your project file to turn off the dllimports.
|
||||
#ifndef CTEMPLATE_DLL_DECL
|
||||
# define CTEMPLATE_DLL_DECL __declspec(dllimport)
|
||||
extern template class __declspec(dllimport) std::allocator<std::string>;
|
||||
extern template class __declspec(dllimport) std::vector<std::string>;
|
||||
#else
|
||||
template class __declspec(dllexport) std::allocator<std::string>;
|
||||
template class __declspec(dllexport) std::vector<std::string>;
|
||||
#endif
|
||||
|
||||
namespace ctemplate {
|
||||
|
|
|
@ -187,18 +187,31 @@ extern CTEMPLATE_DLL_DECL CleanseCss cleanse_css;
|
|||
// url that doesn't have a protocol hidden in it (ie [foo.html] is
|
||||
// fine, but not [javascript:foo]) and then performs another type of
|
||||
// escaping. Returns the url escaped with the specified modifier if
|
||||
// good, otherwise returns "#".
|
||||
// good, otherwise returns a safe replacement URL.
|
||||
// This is normally "#", but for <img> tags, it is not safe to set
|
||||
// the src attribute to "#". This is because this causes some browsers
|
||||
// to reload the page, which can cause a DoS.
|
||||
class CTEMPLATE_DLL_DECL ValidateUrl : public TemplateModifier {
|
||||
public:
|
||||
explicit ValidateUrl(const TemplateModifier& chained_modifier)
|
||||
: chained_modifier_(chained_modifier) { }
|
||||
explicit ValidateUrl(const TemplateModifier& chained_modifier,
|
||||
const char* unsafe_url_replacement)
|
||||
: chained_modifier_(chained_modifier),
|
||||
unsafe_url_replacement_(unsafe_url_replacement),
|
||||
unsafe_url_replacement_length_(strlen(unsafe_url_replacement)) { }
|
||||
MODIFY_SIGNATURE_;
|
||||
static const char* const kUnsafeUrlReplacement;
|
||||
static const char* const kUnsafeImgSrcUrlReplacement;
|
||||
private:
|
||||
const TemplateModifier& chained_modifier_;
|
||||
const char* unsafe_url_replacement_;
|
||||
int unsafe_url_replacement_length_;
|
||||
};
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_html_escape;
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_javascript_escape;
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_url_and_css_escape;
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_html_escape;
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_javascript_escape;
|
||||
extern CTEMPLATE_DLL_DECL ValidateUrl validate_img_src_url_and_css_escape;
|
||||
|
||||
// Escapes < > & " ' to < > & " ' (same as in HtmlEscape).
|
||||
// If you use it within a CDATA section, you may be escaping more characters
|
||||
|
|
|
@ -58,6 +58,21 @@ DLLDEF_DEFINES="\
|
|||
# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\
|
||||
#endif"
|
||||
|
||||
# template_cache.h gets a special DEFINE to work around the
|
||||
# difficulties in dll-exporting stl containers. Ugh.
|
||||
TEMPLATE_CACHE_DLLDEF_DEFINES="\
|
||||
// NOTE: if you are statically linking the template library into your binary\n\
|
||||
// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\
|
||||
// as a compiler flag in your project file to turn off the dllimports.\n\
|
||||
#ifndef $DLLDEF_MACRO_NAME\n\
|
||||
# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\
|
||||
extern template class __declspec(dllimport) std::allocator<std::string>;\n\
|
||||
extern template class __declspec(dllimport) std::vector<std::string>;\n\
|
||||
#else\n\
|
||||
template class __declspec(dllexport) std::allocator<std::string>;\n\
|
||||
template class __declspec(dllexport) std::vector<std::string>;\n\
|
||||
#endif"
|
||||
|
||||
# Read all the windows config info into variables
|
||||
# In order for the 'set' to take, this requires putting all in a subshell.
|
||||
(
|
||||
|
@ -72,13 +87,16 @@ DLLDEF_DEFINES="\
|
|||
echo "Processing $file"
|
||||
outfile="$1/windows/ctemplate/`basename $file .in`"
|
||||
|
||||
if test "`basename $file`" = template_cache.h.in; then
|
||||
MY_DLLDEF_DEFINES=$TEMPLATE_CACHE_DLLDEF_DEFINES
|
||||
else
|
||||
MY_DLLDEF_DEFINES=$DLLDEF_DEFINES
|
||||
fi
|
||||
|
||||
# Besides replacing @...@, we also need to turn on dllimport
|
||||
# We also need to replace hash by hash_compare (annoying we hard-code :-( )
|
||||
# Finally, we get rid of the header files that try to find @ac_cv_unit64@
|
||||
# We tell them by their comment: "a place @ac_cv_uint64@ might live".
|
||||
# Except it has a typo and says "unit64", so I check for both.
|
||||
sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \
|
||||
-e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \
|
||||
-e "s!@ac_windows_dllexport_defines@!$MY_DLLDEF_DEFINES!g" \
|
||||
-e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \
|
||||
-e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \
|
||||
-e "s!@ac_cv_cxx_hash_map_class@!$HASH_NAMESPACE::hash_map!g" \
|
||||
|
|
Loading…
Reference in New Issue
Block a user