diff options
| author | Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de> | 2026-02-27 14:50:39 +0100 |
|---|---|---|
| committer | David Siegfried <david.siegfried@uni-vechta.de> | 2026-02-27 13:50:39 +0000 |
| commit | ce679651ccf784da2e4bf57d53b57d895a4fbea3 (patch) | |
| tree | 5946f87af5fcd461808285488fcfc8258afd863b | |
| parent | e752624e6621cda3e9821694d0699e2c91224746 (diff) | |
fix XSS issues with date formatting, fixes #6277
Closes #6277
Merge request studip/studip!4751
| -rw-r--r-- | app/controllers/admin/courses.php | 7 | ||||
| -rw-r--r-- | app/controllers/course/block_appointments.php | 4 | ||||
| -rw-r--r-- | app/controllers/course/overview.php | 2 | ||||
| -rw-r--r-- | app/controllers/course/timesrooms.php | 24 | ||||
| -rw-r--r-- | app/controllers/tree.php | 2 | ||||
| -rw-r--r-- | app/views/course/overview/index.php | 4 | ||||
| -rw-r--r-- | app/views/course/room_requests/_new_request_header.php | 2 | ||||
| -rw-r--r-- | app/views/resources/_common/_request_info.php | 2 | ||||
| -rw-r--r-- | app/views/resources/_common/_request_tr.php | 2 | ||||
| -rw-r--r-- | app/views/resources/admin/global_locks.php | 2 | ||||
| -rw-r--r-- | app/views/resources/booking/add_from_request.php | 2 | ||||
| -rw-r--r-- | app/views/resources/room_request/planning.php | 2 | ||||
| -rw-r--r-- | app/views/resources/room_request/resolve.php | 2 | ||||
| -rw-r--r-- | lib/models/CourseDate.php | 6 | ||||
| -rw-r--r-- | lib/models/SeminarCycleDate.php | 28 | ||||
| -rw-r--r-- | lib/models/resources/ResourceRequest.php | 2 | ||||
| -rw-r--r-- | templates/dates/course_date_list.php | 24 | ||||
| -rw-r--r-- | templates/filesystem/topic_folder/description.php | 2 |
18 files changed, 71 insertions, 48 deletions
diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php index fb65f70..38ce72b 100644 --- a/app/controllers/admin/courses.php +++ b/app/controllers/admin/courses.php @@ -658,8 +658,7 @@ class Admin_CoursesController extends AuthenticatedController $d['type'] = htmlReady($semtype['name']); } if (in_array('room_time', $activated_fields)) { - $strings = $course->getAllDatesInSemester($this->semester)->toStringArray(); - $d['room_time'] = implode('<br>', $strings) ?: _('nicht angegeben'); + $d['room_time'] = $course->getAllDatesInSemester($this->semester)->toHtml(); } if (in_array('semester', $activated_fields)) { $d['semester'] = htmlReady($course->semester_text); @@ -1005,9 +1004,7 @@ class Admin_CoursesController extends AuthenticatedController } if (in_array('room_time', $filter_config)) { - $dates = $course->getAllDatesInSemester($this->semester); - $date_strings = $dates->toStringArray(true); - $row['room_time'] = implode("\n", $date_strings) ?: _('nicht angegeben'); + $row['room_time'] = (string) $course->getAllDatesInSemester($this->semester); } if (in_array('requests', $filter_config)) { diff --git a/app/controllers/course/block_appointments.php b/app/controllers/course/block_appointments.php index 9e6b9c2..c735244 100644 --- a/app/controllers/course/block_appointments.php +++ b/app/controllers/course/block_appointments.php @@ -272,11 +272,11 @@ class Course_BlockAppointmentsController extends AuthenticatedController } if ($result && $booking_failures) { //Not all selected rooms for the date could be booked: - $partially_booked_dates[] = $d->getFullName(); + $partially_booked_dates[] = htmlReady($d->getFullName()); } } - return $result ? $d->getFullName() : null; + return $result ? htmlReady($d->getFullName()) : null; }, $dates)); if ($date_count > 1) { diff --git a/app/controllers/course/overview.php b/app/controllers/course/overview.php index fc0f441..4325de8 100644 --- a/app/controllers/course/overview.php +++ b/app/controllers/course/overview.php @@ -67,7 +67,7 @@ class Course_OverviewController extends AuthenticatedController $this->next_date = $this->course->getNextDate(); $this->first_date = $this->course->getFirstDate(); $show_link = $GLOBALS["perm"]->have_studip_perm('autor', $this->course_id) && $this->course->isToolActive('schedule'); - $this->times_rooms = implode('<br>', $this->course->getAllDatesInSemester()->toStringArray()); + $this->times_rooms = $this->course->getAllDatesInSemester()->toHtml(); //Load lecturers: $lecturers = $this->course->getMembersWithStatus('dozent'); diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php index ae2c567..8349445 100644 --- a/app/controllers/course/timesrooms.php +++ b/app/controllers/course/timesrooms.php @@ -371,7 +371,7 @@ class Course_TimesroomsController extends AuthenticatedController PageLayout::postWarning( studip_interpolate( _('Die Buchung des Raumes %{room_name} zu diesem Termin wird bei der Verlängerung des Zeitbereiches gelöscht, da sie keine Buchungsrechte an dem Raum haben!'), - ['room_name' => $room->name] + ['room_name' => htmlReady($room->name)] ) ); } @@ -759,9 +759,9 @@ class Course_TimesroomsController extends AuthenticatedController studip_interpolate( _('Der Raum %{room_name} wird an dem Termin %{date} bereits durch die Veranstaltung %{course_name} belegt.'), [ - 'room_name' => $room->name, - 'date' => $termin->getFullName(), - 'course_name' => $course->name + 'room_name' => htmlReady($room->name), + 'date' => htmlReady($termin->getFullName()), + 'course_name' => htmlReady($course->name) ] ), $message_links @@ -771,8 +771,8 @@ class Course_TimesroomsController extends AuthenticatedController studip_interpolate( _('Der Raum %{room_name} wird an dem Termin %{date} bereits anderweitig belegt.'), [ - 'room_name' => $room->name, - 'date' => $termin->getFullName() + 'room_name' => htmlReady($room->name), + 'date' => htmlReady($termin->getFullName()) ] ), $message_links @@ -1309,7 +1309,7 @@ class Course_TimesroomsController extends AuthenticatedController $error_messages[] = sprintf( studip_interpolate( _('%{date}: Die eingegebene Rüstzeit überschreitet das erlaubte Maximum von %d Minuten!'), - ['date' => $singledate->getFullName()] + ['date' => htmlReady($singledate->getFullName())] ), $max_preparation_time ); @@ -1334,17 +1334,17 @@ class Course_TimesroomsController extends AuthenticatedController $error_messages[] = studip_interpolate( _('Der Raum %{room_name} wird an dem Termin %{date} bereits durch die Veranstaltung %{course_name} belegt.'), [ - 'room_name' => $room->name, - 'date' => $singledate->getFullName(), - 'course_name' => $course->name + 'room_name' => htmlReady($room->name), + 'date' => htmlReady($singledate->getFullName()), + 'course_name' => htmlReady($course->name) ] ); } else { $error_messages[] = studip_interpolate( _('Der Raum %{room_name} wird an dem Termin %{date} bereits anderweitig belegt.'), [ - 'room_name' => $room->name, - 'date' => $singledate->getFullName() + 'room_name' => htmlReady($room->name), + 'date' => htmlReady($singledate->getFullName()) ] ); } diff --git a/app/controllers/tree.php b/app/controllers/tree.php index 22135a5..9bde648 100644 --- a/app/controllers/tree.php +++ b/app/controllers/tree.php @@ -39,7 +39,7 @@ class TreeController extends AuthenticatedController $course->veranstaltungsnummer, $course->getFullName('type-number-name'), $course->getTextualSemester(), - strip_tags(implode("\n", $course->getAllDatesInSemester()->toStringArray())), + implode("\n", $course->getAllDatesInSemester()->toStringArray()), implode(', ', $lecturers), implode("\n", $studyAreaPaths) ]; diff --git a/app/views/course/overview/index.php b/app/views/course/overview/index.php index 03fc848..fa14efd 100644 --- a/app/views/course/overview/index.php +++ b/app/views/course/overview/index.php @@ -17,12 +17,12 @@ </dd> <? if ($next_date) : ?> <dt><?= _('Nächster Termin') ?></dt> - <dd><?= $next_date->getFullName('long') ?></dd> + <dd><?= htmlReady($next_date->getFullName('long')) ?></dd> <? else : ?> <dt><?= _('Erster Termin') ?></dt> <dd> <? if ($first_date) : ?> - <?= $first_date->getFullName('long') ?> + <?= htmlReady($first_date->getFullName('long')) ?> <? else : ?> <?= _('Die Zeiten der Veranstaltung stehen nicht fest.') ?> <? endif ?> diff --git a/app/views/course/room_requests/_new_request_header.php b/app/views/course/room_requests/_new_request_header.php index cd0d381..c63d8a8 100644 --- a/app/views/course/room_requests/_new_request_header.php +++ b/app/views/course/room_requests/_new_request_header.php @@ -7,7 +7,7 @@ <? $dates = $request->getDateString(true); ?> - <?= tooltipHtmlIcon(implode('<br>', $dates)) ?> + <?= tooltipHtmlIcon(implode('<br>', array_map('htmlReady', $dates))) ?> <? endif ?> </section> </section> diff --git a/app/views/resources/_common/_request_info.php b/app/views/resources/_common/_request_info.php index 8a0c7b4..c698fad 100644 --- a/app/views/resources/_common/_request_info.php +++ b/app/views/resources/_common/_request_info.php @@ -5,7 +5,7 @@ ?> <dl> <dt><?= _('Termine') ?>:</dt> - <dd><?= $request->getDateString() ?></dd> + <dd><?= htmlReady($request->getDateString()) ?></dd> <dt><?= !empty($timesrooms_page) ? _('Rüstzeit vor dem Termin') : _('Rüstzeit vor der Buchung') ?>:</dt> <dd> <? $preparation_time_minutes = intval($request->preparation_time / 60) ?> diff --git a/app/views/resources/_common/_request_tr.php b/app/views/resources/_common/_request_tr.php index 8f0510e..7c18ed1 100644 --- a/app/views/resources/_common/_request_tr.php +++ b/app/views/resources/_common/_request_tr.php @@ -49,7 +49,7 @@ </td> <? $intervals = $request->getTimeIntervals() ?> <td data-sort-value="<?= htmlReady(isset($intervals[0]) ? $intervals[0]['begin'] : '') ?>"> - <?= $request->getTypeString() ?> + <?= htmlReady($request->getTypeString()) ?> <? if ($request->isSimpleRequest()): ?> <? $begin = $request->getStartDate(); diff --git a/app/views/resources/admin/global_locks.php b/app/views/resources/admin/global_locks.php index ef6bccd..6f44630 100644 --- a/app/views/resources/admin/global_locks.php +++ b/app/views/resources/admin/global_locks.php @@ -13,7 +13,7 @@ <tr> <td><?= date('d.m.Y H:i', $lock->begin) ?></td> <td><?= date('d.m.Y H:i', $lock->end) ?></td> - <td><?= $lock->getTypeString() ?></td> + <td><?= htmlReady($lock->getTypeString()) ?></td> <td class="actions"> <?= ActionMenu::get()->setContext( sprintf( diff --git a/app/views/resources/booking/add_from_request.php b/app/views/resources/booking/add_from_request.php index e7c3d37..f5b5573 100644 --- a/app/views/resources/booking/add_from_request.php +++ b/app/views/resources/booking/add_from_request.php @@ -12,7 +12,7 @@ <legend><?= _('Details zur Anfrage') ?></legend> <h3><?= _('Angefragte Zeiträume')?></h3> <ul> - <? $appointments = explode("\n", $request->getDateString()) ?> + <? $appointments = $request->getDateString(true) ?> <? foreach ($appointments as $appointment): ?> <li><?= htmlReady($appointment) ?></li> <? endforeach ?> diff --git a/app/views/resources/room_request/planning.php b/app/views/resources/room_request/planning.php index 8011dee..1b6c6a3 100644 --- a/app/views/resources/room_request/planning.php +++ b/app/views/resources/room_request/planning.php @@ -285,7 +285,7 @@ <? endif ?> </td> <td> - <?= $request->getTypeString() ?> + <?= htmlReady($request->getTypeString()) ?> </td> </tr> <? endforeach ?> diff --git a/app/views/resources/room_request/resolve.php b/app/views/resources/room_request/resolve.php index 8156dc2..9d4aab8 100644 --- a/app/views/resources/room_request/resolve.php +++ b/app/views/resources/room_request/resolve.php @@ -125,7 +125,7 @@ <dd> <? $dates = $request->getDateString(true, false) ?> <? if ($dates) : ?> - <?= implode('<br>', $dates) ?> + <?= implode('<br>', array_map('htmlReady', $dates)) ?> <? else : ?> <?= _('Keine') ?> <? endif ?> diff --git a/lib/models/CourseDate.php b/lib/models/CourseDate.php index 87a56e8..91182c6 100644 --- a/lib/models/CourseDate.php +++ b/lib/models/CourseDate.php @@ -370,11 +370,7 @@ class CourseDate extends SimpleORMap implements PrivacyObject, Event $rooms = $this->getRooms(); if ($rooms) { foreach ($rooms as $room) { - $string = sprintf('%s <a href="%s" target="_blank">%s</a>', - $string, - $room->getActionURL('booking_plan'), - htmlReady($room->name) - ); + $string .= ' ' . $room->name; } } elseif ($this->raum) { //Use the freetext room name: diff --git a/lib/models/SeminarCycleDate.php b/lib/models/SeminarCycleDate.php index e400665..799cd4a 100644 --- a/lib/models/SeminarCycleDate.php +++ b/lib/models/SeminarCycleDate.php @@ -214,7 +214,7 @@ class SeminarCycleDate extends SimpleORMap * * @returns string The formatted string. */ - public function toString(string $format = 'short') : string + public function toString(string $format = 'short', bool $as_html = false) : string { if (!in_array($format, ['short', 'long', 'long-start', 'full'])) { //Invalid format: @@ -246,16 +246,24 @@ class SeminarCycleDate extends SimpleORMap $room = $this->getMostBookedRoom(); if ($room) { - $parameters['room_name'] = sprintf( - '<a href="%1$s" data-dialog="size=auto">%2$s</a>', - $room->getActionLink(), - htmlReady($room->name) - ); + if ($as_html) { + $parameters['room_name'] = sprintf( + '<a href="%1$s" data-dialog="size=auto">%2$s</a>', + $room->getActionLink(), + htmlReady($room->name) + ); + } else { + $parameters['room_name'] = $room->name; + } } else { //Use the freetext room name: $room = $this->getMostUsedFreetextRoomName(); if ($room) { - $parameters['room_name'] = $room; + if ($as_html) { + $parameters['room_name'] = htmlReady($room); + } else { + $parameters['room_name'] = $room; + } } } $first_date = $this->getFirstDate(); @@ -273,7 +281,11 @@ class SeminarCycleDate extends SimpleORMap } elseif ($format === 'full') { $parameters['start_week'] = $this->week_offset + 1; if ($this->description) { - $parameters['description'] = $this->description; + if ($as_html) { + $parameters['description'] = htmlReady($this->description); + } else { + $parameters['description'] = $this->description; + } } if ($this->end_offset) { $parameters['end_week'] = $this->end_offset; diff --git a/lib/models/resources/ResourceRequest.php b/lib/models/resources/ResourceRequest.php index 0fe0342..79969b3 100644 --- a/lib/models/resources/ResourceRequest.php +++ b/lib/models/resources/ResourceRequest.php @@ -1577,7 +1577,7 @@ class ResourceRequest extends SimpleORMap implements PrivacyObject, Studip\Calen $begin_date = date('Ymd', $this->begin); $end_date = date('Ymd', $this->end); if($this->resource) { - $resource_name = htmlReady($this->resource->getFullName()); + $resource_name = $this->resource->getFullName(); } if ($begin_date == $end_date) { $strings[] = strftime('%a., %x, %R', $this->begin) . ' - ' diff --git a/templates/dates/course_date_list.php b/templates/dates/course_date_list.php index 8fdcd69..0a7bf41 100644 --- a/templates/dates/course_date_list.php +++ b/templates/dates/course_date_list.php @@ -12,14 +12,32 @@ <? if (!$collection->isEmpty()) : ?> <ul class="list-unstyled"> <? foreach ($collection->getRegularDates() as $regular_date) : ?> - <li><?= $regular_date->toString('long-start') ?></li> + <li> + <?= $regular_date->toString('long-start', true) ?> + </li> <? endforeach ?> <? foreach ($collection->getSingleDates() as $single_date) : ?> - <li><?= $single_date->getFullName($with_room_names ? 'long-include-room' : 'long') ?></li> + <li> + <?= htmlReady($single_date->getFullName('long')) ?> + <? if ($with_room_names): ?> + <? $rooms = $single_date->getRooms() ?> + <? if ($rooms): ?> + <? foreach ($rooms as $room): ?> + <a href="<?= $room->getActionLink() ?>" data-dialog> + <?= htmlReady($room->name) ?> + </a> + <? endforeach ?> + <? else: ?> + <?= htmlReady($single_date->raum) ?> + <? endif ?> + <? endif ?> + </li> <? endforeach ?> <? if ($with_cancelled_dates) : ?> <? foreach ($collection->getCancelledDates() as $cancelled_date) : ?> - <li><?= $cancelled_date->getFullName() ?></li> + <li> + <?= htmlReady($cancelled_date->getFullName()) ?> + </li> <? endforeach ?> <? endif ?> </ul> diff --git a/templates/filesystem/topic_folder/description.php b/templates/filesystem/topic_folder/description.php index b80740f..9028773 100644 --- a/templates/filesystem/topic_folder/description.php +++ b/templates/filesystem/topic_folder/description.php @@ -12,7 +12,7 @@ <?=_('Folgende Termine sind diesem Thema zugeordnet:') ?> <div> <strong> - <?=join('; ', $dates)?> + <?= htmlReady(join('; ', $dates)) ?> </strong> </div> <? endif ?> |
