Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions devel/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ def __init__(self, href, title, desc):
self.desc = desc

def __str__(self):
link = '<a href="%s" title="%s">%s</a>'
return format_html(link % (self.href, self.title, self.desc))
return format_html('<a href="{href}" title="{title}">{desc}</a>',
href=self.href, title=self.title, desc=self.desc)


def linkify_non_reproducible_packages(statuses):
Expand Down
10 changes: 10 additions & 0 deletions devel/tests/test_reports.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib.auth.models import User
from django.test import TransactionTestCase

from devel.reports import Linkify
from packages.models import PackageRelation


Expand Down Expand Up @@ -98,3 +99,12 @@ def test_report_pkgbases_filtered_by_maintainer(self):
f'/devel/reports/old/{self.user.username}/pkgbases/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content.decode().strip(), 'linux')


def test_linkify_escapes_html():
link = Linkify(href='"><script>alert(1)</script>', title='<img onerror=alert(1)>', desc='<b>xss</b>')
result = str(link)
assert '<script>' not in result
assert '<img' not in result
assert '<b>' not in result
assert '&lt;script&gt;' in result
6 changes: 3 additions & 3 deletions devel/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import hmac
import operator
import time
from datetime import timedelta
Expand Down Expand Up @@ -143,9 +144,8 @@ def clock(request):
latest_signoff = dict(Signoff.objects.filter(
user__is_active=True).values_list('user').order_by().annotate(
last_signoff=Max('created')))
# The extra() bit ensures we can use our 'user_id IS NOT NULL' index
latest_flagreq = dict(FlagRequest.objects.filter(
user__is_active=True).extra(where=['user_id IS NOT NULL']).values_list(
user__is_active=True, user_id__isnull=False).values_list(
'user_id').order_by().annotate(last_flagrequest=Max('created')))
latest_log = dict(LogEntry.objects.filter(
user__is_active=True).values_list('user').order_by().annotate(
Expand Down Expand Up @@ -236,7 +236,7 @@ def tier0_mirror_auth(request):
if not user:
return unauthorized

if user and token == user.userprofile.repos_auth_token:
if user and hmac.compare_digest(token, user.userprofile.repos_auth_token):
return HttpResponse('Authorized')
else:
return unauthorized
Expand Down
3 changes: 1 addition & 2 deletions main/templatetags/cdn.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django import template
from django.contrib.staticfiles.storage import staticfiles_storage
from django.utils.html import format_html
from django.utils.safestring import mark_safe

register = template.Library()

Expand All @@ -11,7 +10,7 @@ def jquery() -> str:
version = '3.6.0'
filename = f'jquery-{version}.min.js'
link = staticfiles_storage.url(filename)
return mark_safe(f'<script type="text/javascript" src="{link}"></script>')
return format_html('<script type="text/javascript" src="{link}"></script>', link=link)


@register.simple_tag
Expand Down
2 changes: 2 additions & 0 deletions news/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django import forms
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.mail import EmailMessage
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect
Expand Down Expand Up @@ -82,6 +83,7 @@ def view_redirect(request, object_id):
return redirect(newsitem, permanent=True)


@login_required
@require_POST
def preview(request):
data = request.POST.get('data', '')
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ requires-python = ">=3.13"
dependencies = [
"bencode-py==4.1.0",
"bleach==6.4.0",
"django==5.2.16",
"django==5.2.17",
"django-countries==8.2.0",
"django-csp==4.0",
"django-prometheus==2.5.0",
Expand Down
21 changes: 17 additions & 4 deletions sitestatic/homepage.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,24 @@
ul.style.display = "block";
const fragment = document.createDocumentFragment();

for (let i = 0; i < pkgs.length; i++) {
for (const pkgname of pkgs) {
const item = document.createElement("li");
const text = pkgs[i].replace(letter, `<b>${letter}</b>`);
item.innerHTML = `<a href="#">${text}</a>`;
item.setAttribute('data-value', pkgs[i]);
const anchor = document.createElement("a");
anchor.href = "#";

const matchIndex = pkgname.indexOf(letter);
if (matchIndex !== -1) {
anchor.appendChild(document.createTextNode(pkgname.slice(0, matchIndex)));
const bold = document.createElement("b");
bold.textContent = pkgname.slice(matchIndex, matchIndex + letter.length);
anchor.appendChild(bold);
anchor.appendChild(document.createTextNode(pkgname.slice(matchIndex + letter.length)));
} else {
anchor.textContent = pkgname;
}

item.appendChild(anchor);
item.setAttribute('data-value', pkgname);
fragment.appendChild(item);
}

Expand Down
8 changes: 4 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading