Commit Graph

102 Commits

Author SHA1 Message Date
Augie Fackler
d57f1641f5 templatefilters: defend against evil unicode strs in json filter
We only want to do I/O in terms of bytes, so lets explode early
instead of recursing forever.

Differential Revision: https://phab.mercurial-scm.org/D1136
2017-10-16 22:44:43 -04:00
Augie Fackler
a67386352a python3: use our bytes-only version of cgi.escape everywhere
As suggested by Yuya in D965.

Differential Revision: https://phab.mercurial-scm.org/D1067
2017-10-05 14:16:20 -04:00
Yuya Nishihara
a71f259bd2 doctest: bulk-replace string literals with b'' for Python 3
Our code transformer can't rewrite string literals in docstrings, and I
don't want to make the transformer more complex.
2017-09-03 14:32:11 +09:00
Yuya Nishihara
91bdea4c9e json: pass formatting options recursively
This bug was introduced in 469914605447. It's okay to escape <>, but is
unnecessary for command output.
2017-06-09 21:33:15 +09:00
Yuya Nishihara
6eaf988ce2 json: avoid extra string manipulation of dict keys
A key must be string per JSON spec, and that's also true for template dicts.
2017-04-23 13:40:18 +09:00
Yuya Nishihara
03fcc62be8 templatefilers: correct filename in header comment 2017-06-09 21:28:22 +09:00
Pulkit Goyal
ce6291f190 py3: replace str with bytes in isinstance() 2017-04-20 19:57:16 +05:30
Pulkit Goyal
c5fa590c26 py3: use pycompat.bytestr() instead of str()
This is because str() on python 3 return unicodes
2017-04-27 09:49:57 +05:30
Pulkit Goyal
ba8a84e565 py3: alias long to int on Python 3 2017-04-20 19:51:37 +05:30
Yuya Nishihara
e952ac99ea templatefilters: fix crash by string formatting of '{x|splitlines}'
Before, it crashed because mapping['templ'] was missing. As it didn't support
the legacy list template from the beginning, we can simply use hybridlist().
2017-04-15 10:51:17 +09:00
Yuya Nishihara
e83ec90299 templatekw: have showlist() take mapping dict with no **kwargs expansion (API)
See the previous commit for why.

splitlines() does not pass a mapping dict, which would probably mean the
legacy template didn't work from the beginning.
2017-04-05 21:47:34 +09:00
Yuya Nishihara
e6ea93a8d4 templater: remove __iter__() from _hybrid, resolve it explicitly
The goal is to fix "{hybrid_obj|json}" output.

A _hybrid object must act as a list or a dict as well as a generator of
legacy template strings. Before, _hybrid.__iter__() was assigned for legacy
template, which conflicted with list.__iter__() API.

This patch drops _hybrid.__iter__() and makes stringify/flatten functions
unwrap a generator instead.
2017-04-04 22:19:02 +09:00
Yuya Nishihara
ce44b9ffb0 formatter: use templatefilters.json()
Now _jsonifyobj() is identical to templatefilters.json(paranoid=False).
2017-04-02 12:02:17 +09:00
Yuya Nishihara
ccd02d13b3 templatefilters: use list comprehension in json()
Not important, but the code slightly looks better.
2017-04-02 11:54:24 +09:00
Yuya Nishihara
67ba45c194 templatefilters: unroll handling of None/False/True
It doesn't make sense to use a dict here.
2017-04-02 11:51:25 +09:00
Yuya Nishihara
c5537c8613 templatefilters: drop callable support from json()
This backs out 1e5c61c691c5. A callable should be evaluated beforehand
by templater.runsymbol().
2017-04-02 11:46:49 +09:00
Matt Harbison
5bca44776e templatefilter: add support for 'long' to json()
When disabling the '#requires serve' check in test-hgwebdir.t and running it on
Windows, several 500 errors popped up when querying '?style=json', with the
following in the error log:

    File "...\\mercurial\\templater.py", line 393, in runfilter
      "keyword '%s'") % (filt.func_name, dt))
    Abort: template filter 'json' is not compatible with keyword 'lastchange'

The swallowed exception at that point was:

    File "...\\mercurial\\templatefilters.py", line 242, in json
      raise TypeError('cannot encode type %s' % obj.__class__.__name__)
    TypeError: cannot encode type long

This corresponds to 'lastchange' being populated by hgweb.common.get_stat(),
which uses os.stat().st_mtime.  os.stat_float_times() is being disabled in util,
so the type for the times is 'long' on Windows, and 'int' on Linux.
2017-04-01 00:21:17 -04:00
Yuya Nishihara
02022fc3c5 util: wrap s.encode('string_escape') call for future py3 compatibility 2017-03-15 23:06:50 +09:00
timeless
109fcbc79e pycompat: switch to util.urlreq/util.urlerr for py3 compat 2016-04-06 23:22:12 +00:00
FUJIWARA Katsunori
15ff9ca52f templatefilters: use templatefilter to mark a function as template filter
Using decorator can localize changes for adding (or removing) a
template filter function in source code.

This patch also removes leading ":FILTER:" part in help document of
each filters, because using templatefilter makes it useless.

This patch uses not 'filter' but 'templatefilter' as a decorator name,
because the former name hides Python built-in one, even though the
latter is a little redundant in 'templatefilters.py'.
2016-03-30 02:10:44 +09:00
FUJIWARA Katsunori
098aa2f5a6 registrar: add templatefilter to mark a function as template filter (API)
This patch also adds loadfilter() to templatefilters, because this
combination helps to figure out how they cooperate with each other.

Listing up loadfilter() in dispatch.extraloaders causes implicit
loading template filter functions at loading (3rd party) extension.

This change requires that "templatefilter" attribute of (3rd party)
extension is registrar.templatefilter or so.
2016-03-30 02:10:44 +09:00
Yuya Nishihara
088b5128e7 templatefilters: drop old jsonescape() function
It's been superseded by encoding.jsonescape(paranoid=True).
2015-12-27 18:50:03 +09:00
Yuya Nishihara
2e33bbee20 templatefilters: make json filter be byte-transparent (BC) (issue4926)
This is necessary to preserve filename encoding over JSON. Instead, this
patch inserts "|utf8" where non-ascii local-encoding texts can be passed
to "|json".

See also the commit that introduced "utf8" filter.
2015-12-27 17:59:57 +09:00
Yuya Nishihara
5236f2a921 templatefilters: add "utf8" to get utf-8 bytes from local-encoding text
This will be applied prior to "|json" filter. This sounds like odd, but it
is necessary to handle local-encoding text as well as raw filename bytes.

Because filenames are bytes in Mercurial and Unix world, {filename|json} should
preserve the original byte sequence, which implies

  {x|json} -> '"' toutf8b(x) '"'

On the other hand, most template strings are in local encoding. Because
"|json" filter have to be byte-transparent to filenames, we need something to
annotate an input as a local string, that's what "|utf8" will do.

  {x|utf8|json} -> '"' toutf8b(fromlocal(x)) '"'

"|utf8" is an explicit call, so aborts if input bytes can't be converted to
UTF-8.
2015-12-27 17:45:05 +09:00
Yuya Nishihara
064b729470 templatefilters: drop broken "jsonescape" from filters table (BC)
It's been unused, undocumented and flawed in that it expects a unicode input,
never works correctly if an input has non-ascii character. We should use "json"
filter instead.
2015-12-27 17:16:45 +09:00
Matt Mackall
61d5d53d27 merge with stable 2015-11-04 15:17:52 -06:00
Yuya Nishihara
dda890d7ab templatefilters: try round-trip utf-8 conversion by json filter (issue4933)
As JSON string is known to be a unicode, we should try round-trip conversion
for localstr type. This patch tests localstr type explicitly because
encoding.fromlocal() may raise Abort for undecodable str, which is probably
not what we want. Maybe we can refactor json filter to use encoding module
more later.

Still "{desc|json}" can't round-trip because showdescription() modifies a
localstr object.
2015-11-04 23:48:15 +09:00
Pierre-Yves David
4258ec762f uescape: also encode non-printable char under 128
We were assuming everything under 128 was printable ascii, but there are a lot
of control characters in that range that can't simply be included in json and
other targets. We forcibly encode everything under 32, because they are either
control char or oddly printable (like tab or line ending).

We also add the hypothesis-powered test that caught this.
2015-11-02 11:56:59 +00:00
Yuya Nishihara
246636f6db templater: port localdate filter to a function
It will be extended to accept a timezone argument.
2015-09-01 19:15:16 +09:00
Yuya Nishihara
4377cc9e4b templatefilters: remove redundant 'date' and 'strip' filters
These filters are defined as 'date()' and 'strip()' functions. Help messages
are moved to the corresponding functions.
2015-07-04 16:07:42 +09:00
Gregory Szorc
edfcac720c templatefilters: use absolute_import 2015-08-08 20:08:52 -07:00
Anton Shestakov
939c576f07 templates: introduce revescape filter for escaping symbolic revisions
There needs to be a way to escape symbolic revisions containing forward
slashes, but urlescape filter doesn't escape slashes at all (in fact, it is
used in places where forward slashes must be preserved).

The filter considers @ to be safe just for bookmarks like @ and @default to
look good in urls.
2015-07-12 16:47:56 +08:00
Jordi Gutiérrez Hermoso
0618dc68e3 templatefilters: don't stringify None into "None"
A few template keywords can in fact return None, such as {bisect}. In
some contexts, these get stringified into None instead of "". This is
leaking Python details into the UI.
2015-05-10 13:33:51 -04:00
Yuya Nishihara
97a7438eb1 templatefilters: add "upper" and "lower" for case conversion
Typically it will be used in patchbomb's flag template, which will be
implemented by future patches.
2015-03-30 23:54:29 +09:00
Gregory Szorc
0103ac9a7b templatefilters.json: stabilize output
The json filter was previously iterating over keys in an object in an
undefined order. Let's throw a sorted() in there so output is
consistent.

It's somewhat frightening that there are no tests for the json filter.
Subsequent commits will add them, so we pass on the opportunity to add
them here.
2014-12-31 13:48:55 -08:00
Gregory Szorc
ad5d2929fc templatefilters.json: call functions
The "changeset" template from hgweb is using a lambda in the
"diffsummary" key. In preparation for enabling JSON output from hgweb,
teach the json filter how to call functions.
2014-12-31 11:22:17 -08:00
Anton Shestakov
ca791cb0ef templater: add count template filter, plus tests
Previously there was no way of telling how much children or bookmarks or tags a
certain changeset has in a template. It was possible to tell if a changeset has
either 0 or not 0 bookmarks, but not to tell if it has 1 or 2 of them, for
example.

This filter, simply named count, makes it possible to count the number of items
in a list or the length of a string (or, anything that python's len can count).
E.g.: {children|count}, {bookmarks|count}, {file_adds|count}.

Testing the filter on node hash and shortened node hash is chosen because they
both have defined length.

As for lists of strings - children, tags and file_adds are used, because they
provide some variety and also prove that what's counted is the number of string
items in the list, and not the list stringified (they are lists of non-empty,
multi-character strings).

Additionally, revset template function is used for testing the filter, since
the combination is very flexible and will possibly be used together a lot.

(The previous version of this patch had an incorrect email subject and was
apparently lost - patchwork says the patch has been accepted, but it's not so.
The changes between that and this patch are minimal: now the filter does not
disturb the alphabetical order of function definitions and dict keys.)
2014-09-09 22:14:13 +09:00
Matt Mackall
5fc8526562 merge with stable 2014-07-14 18:53:03 -05:00
Matt Mackall
de2b99d87c templates: escape NUL bytes in jsonescape (issue4303)
It's currently possible for various fields to contain NUL bytes, which
are disallowed in JSON.
2014-07-14 12:44:45 -05:00
Ryan McElroy
9f5399cbcd templatefilter: add splitlines function
This is useful for applying changes to each line, and it's especially powerful
when used in conjunction with conditionals to modify lines based on content.
2014-06-12 17:45:41 -07:00
Matt Mackall
397a3b5d72 merge with stable 2013-10-09 14:15:34 -07:00
Matt Mackall
23bced957e json: add more paranoid escaping 2013-10-09 11:50:19 -07:00
Mads Kiilerich
1e900bb145 check-code: check for spaces around = for named parameters 2013-10-03 14:50:47 +02:00
David Soria Parra
bd9e14bcec templatefilters: add short format for age formatting
Implements a short output format for ages e.g. "1 second ago" is
abbrevated as "1s ago".
2013-09-17 17:42:13 +02:00
Matt Mackall
dbd9dd9280 template: fix tabindent docstring (issue2880) 2013-07-19 12:58:30 -05:00
Sean Farley
44577c753d templater: add indentation arguments to the fill function 2013-04-18 15:48:22 -05:00
Sean Farley
8a5d9c21d4 templater: move templatefilters.func into the same place as the other funcs 2013-04-10 18:56:38 -05:00
Mads Kiilerich
00a100f5a5 merge with stable 2013-02-28 14:51:59 +01:00
Mads Kiilerich
93a2b8faf0 templatefilters: add missing import of _ 2013-02-28 13:55:00 +01:00
Angel Ezquerra
ed79324ad4 hgweb: add websub template filter
The purpose of this new filter is to make it possible to partially replace the
functionality of the interhg extension. The idea is to be able to define regular
expression based substitutions on a new "websub" config section. hgweb will then
be able to apply these substitutions wherever the "websub" filter is used on a
template.

This first revision just adds the code necessary to load the websub expressions
and adds the websub filter, but it does not add any calls to the websub filter
itself on any of the templates. That will be done on the following revisions.
2013-02-08 18:05:32 +01:00