Skip to content

Commit

Permalink
Remove use of JavaScript eval() (Closes #60)
Browse files Browse the repository at this point in the history
  • Loading branch information
e2jk authored and miguelgrinberg committed Jun 10, 2020
1 parent e506753 commit 5e453fc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 40 deletions.
51 changes: 35 additions & 16 deletions flask_moment.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,19 @@ def include_moment(version=default_moment_version, local_js=None,
return Markup('''%s<script>
moment.locale("en");%s
function flask_moment_render(elem) {
$(elem).text(eval('moment("' + $(elem).data('timestamp') + '").' + $(elem).data('format') + ';'));
timestamp = moment($(elem).data('timestamp'));
func = $(elem).data('function');
format = $(elem).data('format');
timestamp2 = $(elem).data('timestamp2');
no_suffix = $(elem).data('nosuffix');
args = [];
if (format)
args.push(format);
if (timestamp2)
args.push(moment(timestamp2));
if (no_suffix)
args.push(no_suffix);
$(elem).text(timestamp[func].apply(timestamp, args));
$(elem).removeClass('flask-moment').show();
}
function flask_moment_render_all() {
Expand Down Expand Up @@ -119,40 +131,47 @@ def _timestamp_as_iso_8601(self, timestamp):
tz = 'Z'
return timestamp.strftime('%Y-%m-%dT%H:%M:%S' + tz)

def _render(self, format, refresh=False):
def _render(self, func, format=None, timestamp2=None, no_suffix=None,
refresh=False):
t = self._timestamp_as_iso_8601(self.timestamp)
data_values = 'data-function="%s"' % func
if format:
data_values += ' data-format="%s"' % format
if timestamp2:
data_values += ' data-timestamp2="%s"' % timestamp2
if no_suffix:
data_values += ' data-nosuffix="1"'
return Markup(('<span class="flask-moment" data-timestamp="%s" ' +
'data-format="%s" data-refresh="%d" ' +
'%s data-refresh="%d" ' +
'style="display: none">%s</span>') %
(t, format, int(refresh) * 60000, t))
(t, data_values, int(refresh) * 60000, t))

def format(self, fmt=None, refresh=False):
return self._render("format('%s')" % (fmt or ''), refresh)
return self._render("format", format=(fmt or ''), refresh=refresh)

def fromNow(self, no_suffix=False, refresh=False):
return self._render("fromNow(%s)" % int(no_suffix), refresh)
return self._render("fromNow", no_suffix=int(no_suffix),
refresh=refresh)

def fromTime(self, timestamp, no_suffix=False, refresh=False):
return self._render("from(moment('%s'),%s)" %
(self._timestamp_as_iso_8601(timestamp),
int(no_suffix)), refresh)
return self._render("from", timestamp2=self._timestamp_as_iso_8601(
timestamp), no_suffix=int(no_suffix), refresh=refresh)

def toNow(self, no_suffix=False, refresh=False):
return self._render("toNow(%s)" % int(no_suffix), refresh)
return self._render("toNow", no_suffix=int(no_suffix), refresh=refresh)

def toTime(self, timestamp, no_suffix=False, refresh=False):
return self._render("to(moment('%s'),%s)" %
(self._timestamp_as_iso_8601(timestamp),
int(no_suffix)), refresh)
return self._render("to", timestamp2=self._timestamp_as_iso_8601(
timestamp), no_suffix=int(no_suffix), refresh=refresh)

def calendar(self, refresh=False):
return self._render("calendar()", refresh)
return self._render("calendar", refresh=refresh)

def valueOf(self, refresh=False):
return self._render("valueOf()", refresh)
return self._render("valueOf", refresh=refresh)

def unix(self, refresh=False):
return self._render("unix()", refresh)
return self._render("unix", refresh=refresh)


class Moment(object):
Expand Down
40 changes: 19 additions & 21 deletions tests/test_flask_moment.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def test__timestamp_as_iso_8601_local_true(self):
def test__render_default(self):
mom = _moment_mock()
refresh = False
rts = mom._render(format="format") # rts: rendered time stamp
rts = mom._render(func="format") # rts: rendered time stamp

assert isinstance(rts, Markup)
assert rts.find("thisisnotinthemarkup") < 0
Expand All @@ -164,7 +164,7 @@ def test__render_default(self):
def test__render_refresh(self):
mom = _moment_mock()
refresh = True
rts = mom._render(format="format", refresh=refresh)
rts = mom._render(func="format", refresh=refresh)

assert isinstance(rts, Markup)
assert not rts.find("thisisnotinthemarkup") > 0
Expand All @@ -180,26 +180,24 @@ def test_format_default(self):

def test_fromNow_default(self):
mom = _moment_mock()
no_suffix = False
rts = mom.fromNow()

assert rts.find("fromNow(%s)" % int(no_suffix)) > 0
assert rts.find("data-function=\"fromNow\"") > 0

def test_fromNow_no_suffix(self):
mom = _moment_mock()
no_suffix = True
rts = mom.fromNow(no_suffix=no_suffix)

assert rts.find("fromNow(%s)" % int(no_suffix)) > 0
assert rts.find("data-function=\"fromNow\" data-nosuffix=\"1\"") > 0

def test_fromTime_default(self):
mom = _moment_mock()
ts = datetime(2017, 1, 15, 22, 47, 6, 479898)
no_suffix = False
rts = mom.fromTime(timestamp=ts)

assert rts.find("from(moment('%s'),%s)"
% (mom._timestamp_as_iso_8601(ts), int(no_suffix))) > 0
assert rts.find("data-function=\"from\" data-timestamp2=\"%s\""
% mom._timestamp_as_iso_8601(ts)) > 0
assert rts.find("%s" % mom._timestamp_as_iso_8601(
timestamp=mom.timestamp)) > 0

Expand All @@ -209,33 +207,32 @@ def test_fromTime_no_suffix(self):
no_suffix = True
rts = mom.fromTime(timestamp=ts, no_suffix=no_suffix)

assert rts.find("from(moment('%s'),%s)"
% (mom._timestamp_as_iso_8601(ts), int(no_suffix))) > 0
assert rts.find("data-function=\"from\" data-timestamp2=\"%s\" "
"data-nosuffix=\"1\""
% mom._timestamp_as_iso_8601(ts)) > 0
assert rts.find("%s" % mom._timestamp_as_iso_8601(
timestamp=mom.timestamp)) > 0

def test_toNow_default(self):
mom = _moment_mock()
no_suffix = False
rts = mom.toNow()

assert rts.find("toNow(%s)" % int(no_suffix)) > 0
assert rts.find("data-function=\"toNow\"") > 0

def test_toNow_no_suffix(self):
mom = _moment_mock()
no_suffix = True
rts = mom.toNow(no_suffix=no_suffix)

assert rts.find("toNow(%s)" % int(no_suffix)) > 0
assert rts.find("data-function=\"toNow\" data-nosuffix=\"1\"") > 0

def test_toTime_default(self):
mom = _moment_mock()
ts = datetime(2020, 1, 15, 22, 47, 6, 479898)
no_suffix = False
rts = mom.toTime(timestamp=ts)

assert rts.find("to(moment('%s'),%s)"
% (mom._timestamp_as_iso_8601(ts), int(no_suffix))) > 0
assert rts.find("data-function=\"to\" data-timestamp2=\"%s\""
% mom._timestamp_as_iso_8601(ts)) > 0
assert rts.find("%s" % mom._timestamp_as_iso_8601(
timestamp=mom.timestamp)) > 0

Expand All @@ -245,28 +242,29 @@ def test_toTime_no_suffix(self):
no_suffix = True
rts = mom.toTime(timestamp=ts, no_suffix=no_suffix)

assert rts.find("to(moment('%s'),%s)"
% (mom._timestamp_as_iso_8601(ts), int(no_suffix))) > 0
assert rts.find("data-function=\"to\" data-timestamp2=\"%s\" "
"data-nosuffix=\"1\""
% mom._timestamp_as_iso_8601(ts)) > 0
assert rts.find("%s" % mom._timestamp_as_iso_8601(
timestamp=mom.timestamp)) > 0

def test_calendar_default(self):
mom = _moment_mock()
rts = mom.calendar()

assert rts.find("data-format=\"calendar()\"") > 0
assert rts.find("data-function=\"calendar\"") > 0

def test_valueOf_default(self):
mom = _moment_mock()
rts = mom.valueOf()

assert rts.find("data-format=\"valueOf()\"") > 0
assert rts.find("data-function=\"valueOf\"") > 0

def test_unix_default(self):
mom = _moment_mock()
rts = mom.unix()

assert rts.find("data-format=\"unix()\"") > 0
assert rts.find("data-function=\"unix\"") > 0


class TestPublicMomentClass(object):
Expand Down
8 changes: 5 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist=flake8,py27,py34,py35,py36,pypy
envlist=flake8,py27,py35,py36,py37,py38,pypy,pypy3
skip_missing_interpreters=true

[testenv]
Expand All @@ -10,13 +10,15 @@ deps=
mock
basepython=
py27: python2.7
py34: python3.4
py35: python3.5
py36: python3.6
py37: python3.7
py38: python3.8
pypy: pypy
pypy3: pypy3

[testenv:flake8]
basepython=python3.6
basepython=python3.8
commands=
flake8 flask_moment.py tests example
deps=
Expand Down

0 comments on commit 5e453fc

Please sign in to comment.