2022-01-25 20:12:11 +01:00
|
|
|
{% from 'simple/icons.html' import icon_small %}
|
|
|
|
|
|
2017-02-12 15:06:01 +01:00
|
|
|
<!-- Draw favicon -->
|
|
|
|
|
{% macro draw_favicon(favicon) -%}
|
2021-11-25 12:04:39 +01:00
|
|
|
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='themes/simple/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}">
|
2017-02-12 15:06:01 +01:00
|
|
|
{%- endmacro %}
|
|
|
|
|
|
|
|
|
|
{% macro result_open_link(url, classes='') -%}
|
|
|
|
|
<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>
|
|
|
|
|
{%- endmacro %}
|
|
|
|
|
|
|
|
|
|
{%- macro result_close_link() -%}
|
|
|
|
|
</a>
|
|
|
|
|
{%- endmacro %}
|
|
|
|
|
|
|
|
|
|
{%- macro result_link(url, title, classes='') -%}
|
|
|
|
|
{{ result_open_link(url, classes) }}{{ title }}{{ result_close_link() }}
|
|
|
|
|
{%- endmacro -%}
|
|
|
|
|
|
|
|
|
|
<!-- Draw result header -->
|
|
|
|
|
{% macro result_header(result, favicons, image_proxify) -%}
|
2024-12-14 16:35:25 +08:00
|
|
|
<article class="result {% if result['template'] %}result-{{ result.template|replace('.html', '') }}{% else %}result-default{% endif %} {% if result['category'] %}category-{{ result['category'] }}{% endif %}">
|
2024-10-02 18:06:29 +02:00
|
|
|
{{- result_open_link(result.url, "url_header") -}}
|
|
|
|
|
{%- if favicon_resolver != "" %}
|
|
|
|
|
<div class="favicon"><img loading="lazy" src="{{ favicon_url(result.parsed_url.netloc) }}"></div>
|
2024-08-11 08:39:46 +00:00
|
|
|
{%- endif -%}
|
2024-10-02 18:06:29 +02:00
|
|
|
<div class="url_wrapper">
|
|
|
|
|
{%- for part in get_pretty_url(result.parsed_url) -%}
|
|
|
|
|
<span class="url_o{{loop.index}}"><span class="url_i{{loop.index}}">{{- part -}}</span></span>
|
|
|
|
|
{%- endfor %}
|
|
|
|
|
</div>
|
2021-11-21 21:38:00 +01:00
|
|
|
{{- result_close_link() -}}
|
2025-10-12 20:18:10 +02:00
|
|
|
{%- if result.thumbnail %}{{ result_open_link(result.url, classes='thumbnail_link') }}<img class="thumbnail" src="{{ image_proxify(result.thumbnail) }}" title="{{ result.title|striptags }}" loading="lazy">{%- if result.length -%}<span class="thumbnail_length">{{ result.length }}</span>{%- endif -%}{{ result_close_link() }}{% endif -%}
|
2017-02-12 15:06:01 +01:00
|
|
|
<h3>{{ result_link(result.url, result.title|safe) }}</h3>
|
|
|
|
|
{%- endmacro -%}
|
|
|
|
|
|
|
|
|
|
<!-- Draw result sub header -->
|
|
|
|
|
{%- macro result_sub_header(result) -%}
|
2022-04-19 09:32:51 +02:00
|
|
|
{%- if result.publishedDate %}<time class="published_date" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif -%}
|
2025-10-12 20:18:10 +02:00
|
|
|
<!-- Length is displayed inside the thumbnail if there's any, so don't display it here a second time -->
|
|
|
|
|
{%- if result.length and not result.thumbnail %}<div class="result_length">{{ _('Length') }}: {{ result.length }}</div>{% endif -%}
|
2024-07-20 21:27:12 +02:00
|
|
|
{%- if result.views %}<div class="result_views">{{ _('Views') }}: {{ result.views }}</div>{% endif -%}
|
2022-04-19 09:32:51 +02:00
|
|
|
{%- if result.author %}<div class="result_author">{{ _('Author') }}: {{ result.author }}</div>{% endif -%}
|
Fix XSS via unsafe rendering of untrusted external data in templates (#5826)
Remove |safe filter from 6 template locations where data from external
search engine APIs was rendered as raw HTML without sanitization. Jinja2
autoescape now properly escapes these fields.
The |safe filter was originally added in commit 213041adc (March 2021)
by copying the pattern from result.title|safe and result.content|safe.
However, title and content are pre-escaped via escape() in webapp.py
lines 704-706 before highlight_content() adds trusted <span> tags for
search term highlighting. The metadata, info.value, link.url_label,
repository, and filename fields never go through any escaping and flow
directly from external API responses to the template.
Affected templates and their untrusted data sources:
- macros.html: result.metadata from DuckDuckGo, Reuters, Presearch,
Podcast Index, Fyyd, bpb, moviepilot, mediawiki, and others
- paper.html: result.metadata from academic search engines
- map.html: info.value and link.url_label from OpenStreetMap
user-contributed extratags
- code.html: result.repository and result.filename from GitHub API
Example exploit: a search engine API returning
metadata='<img src=x onerror=alert(document.cookie)>' would execute
arbitrary JavaScript in every user's browser viewing that result.
2026-03-13 13:28:31 +01:00
|
|
|
{%- if result.metadata %}<div class="highlight">{{ result.metadata }}</div>{% endif -%}
|
2017-02-12 15:06:01 +01:00
|
|
|
{%- endmacro -%}
|
|
|
|
|
|
|
|
|
|
<!-- Draw result sub footer -->
|
2025-04-05 10:59:07 +02:00
|
|
|
{%- macro result_sub_footer(result) -%}
|
2021-10-07 23:48:52 +02:00
|
|
|
<div class="engines">
|
|
|
|
|
{% for engine in result.engines %}<span>{{ engine }}</span>{% endfor %}
|
2025-04-05 10:59:07 +02:00
|
|
|
{{ icon_small('ellipsis-vertical') + result_link(cache_url + result.url, _('cached'), "cache_link") }}
|
2021-10-07 23:48:52 +02:00
|
|
|
</div>{{- '' -}}
|
2017-02-12 15:06:01 +01:00
|
|
|
<div class="break"></div>{{- '' -}}
|
|
|
|
|
{%- endmacro -%}
|
|
|
|
|
|
|
|
|
|
<!-- Draw result footer -->
|
|
|
|
|
{%- macro result_footer(result) -%}
|
|
|
|
|
</article>
|
|
|
|
|
{%- endmacro -%}
|
|
|
|
|
|
2023-06-02 15:30:02 +02:00
|
|
|
<!-- input checkbox, on/off slider user can tap-->
|
2017-02-12 15:06:01 +01:00
|
|
|
{%- macro checkbox_onoff(name, checked) -%}
|
2023-06-02 15:30:02 +02:00
|
|
|
<input type="checkbox" {{- ' ' -}}
|
|
|
|
|
name="{{ name }}" {{- ' ' -}}
|
|
|
|
|
id="{{ name }}" {{- ' ' -}}
|
|
|
|
|
aria-labelledby="pref_{{ name }}"{{- ' ' -}}
|
|
|
|
|
class="checkbox-onoff"{{- ' ' -}}
|
|
|
|
|
{%- if checked -%} checked{%- endif -%}/>
|
2017-02-12 15:06:01 +01:00
|
|
|
{%- endmacro -%}
|