CUPS wrapper для Kyocera rastertokpsl

Обёртка для CUPS-фильтра rastertokpsl, предназначенная для устранения падений оригинального Kyocera-фильтра при печати заданий с длинными или не-ASCII названиями.

Проблема

Некоторые версии Kyocera rastertokpsl используют фиксированный буфер для обработки названия задания. При передаче длинной строки или строки с кириллицей это может приводить к переполнению буфера и аварийному завершению фильтра:

*** buffer overflow detected ***: terminated

В журналах CUPS это может выглядеть примерно так:

PID 30752 (/usr/lib/cups/filter/rastertokpsl) crashed on signal 6

В результате задание не печатается, а очередь принтера может перейти в состояние stopped.

Решение

Wrapper перехватывает аргументы CUPS перед запуском оригинального rastertokpsl.

Перед передачей названия задания оригинальному фильтру wrapper:

  • преобразует UTF-8 в ASCII;
  • удаляет неподдерживаемые символы;
  • ограничивает длину строки;
  • использует print-job, если после обработки строка оказалась пустой.

Оригинальный бинарник сохраняется под именем:

/usr/lib/cups/filter/rastertokpsl.real

Wrapper устанавливается вместо него:

/usr/lib/cups/filter/rastertokpsl

Установка

Сначала сохраните оригинальный фильтр:

sudo cp /usr/lib/cups/filter/rastertokpsl \
        /usr/lib/cups/filter/rastertokpsl.real

Создайте файл wrapper:

sudo nano /usr/lib/cups/filter/rastertokpsl

Содержимое:

#!/bin/bash

REAL="/usr/lib/cups/filter/rastertokpsl.real"

# Kyocera rastertokpsl uses the following arguments:
# $1 printer
# $2 job-id
# $3 title
# $4 copies
# $5 options

if [ "$#" -ne 5 ]; then
    echo "ERROR: rastertokpsl wrapper: expected 5 arguments, got $#" >&2
    exit 1
fi

printer="$1"
job_id="$2"
title="$3"
copies="$4"
options="$5"

# Convert the title to ASCII, remove unsupported characters,
# and limit its length to 20 characters.
safe_title="$(
    printf '%s' "$title" |
    iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null |
    LC_ALL=C tr -cd 'A-Za-z0-9' |
    tail -c 20
)"

[ -n "$safe_title" ] || safe_title="print-job"

# Pass the raster data through stdin.
exec "$REAL" \
    "$printer" \
    "$job_id" \
    "$safe_title" \
    "$copies" \
    "$options"

Назначьте права:

sudo chown root:root /usr/lib/cups/filter/rastertokpsl
sudo chmod 755 /usr/lib/cups/filter/rastertokpsl
sudo chmod 755 /usr/lib/cups/filter/rastertokpsl.real

Перезапустите CUPS:

sudo systemctl restart cups

Проверка

Убедитесь, что оригинальный файл является исполняемым бинарником:

file /usr/lib/cups/filter/rastertokpsl.real

Ожидается вывод с ELF ... executable.

Проверьте печать обычного задания:

lp -d PRINTER /tmp/test.pdf

Затем проверьте длинное название задания:

lp -d PRINTER \
   -t "Очень длинное кириллическое название задания для проверки" \
   /tmp/test.pdf

Посмотреть состояние очереди:

lpstat -p
lpstat -o

При необходимости включить подробное логирование CUPS:

sudo cupsctl --debug-logging
sudo tail -F /var/log/cups/error_log

После завершения диагностики:

sudo cupsctl --no-debug-logging

Восстановление оригинального фильтра

Чтобы удалить wrapper и вернуть оригинальный rastertokpsl:

sudo mv /usr/lib/cups/filter/rastertokpsl.real \
        /usr/lib/cups/filter/rastertokpsl

sudo systemctl restart cups

Ограничения

Wrapper рассчитан на конкретный вариант интерфейса Kyocera rastertokpsl, использующий пять аргументов:

printer job-id title copies options

Размер 20 символов выбран как консервативное ограничение для проблемных версий фильтра. Точный размер внутреннего буфера конкретной версии rastertokpsl зависит от драйвера и не определяется самим CUPS.

Перед установкой рекомендуется сохранить исходный бинарник и проверить версию драйвера.

Структура

Пример структуры репозитория:

cups-kyocera-rastertokpsl-fix/
├── README.md
└── rastertokpsl

Файл rastertokpsl из репозитория устанавливается в:

/usr/lib/cups/filter/rastertokpsl
S
Description
English: CUPS wrapper for the Kyocera rastertokpsl filter to prevent buffer overflows caused by long or non-ASCII job titles. Русский: Обёртка CUPS для фильтра Kyocera rastertokpsl, предотвращающая переполнение буфера из-за длинных или не-ASCII названий заданий.
Readme 32 KiB
Languages
Shell 100%