| Summary: | Filenames created by exsl:document should be unescaped | ||
|---|---|---|---|
| Product: | Sisyphus | Reporter: | Vitaly A. Ostanin <vyt> |
| Component: | libxslt | Assignee: | Mikhail Zabaluev <mhz> |
| Status: | CLOSED FIXED | QA Contact: | qa-sisyphus |
| Severity: | normal | ||
| Priority: | P2 | CC: | arseny, at, ldv |
| Version: | unstable | ||
| Hardware: | all | ||
| OS: | Linux | ||
У меня тоже есть сомнения, что имена можно безопасно раскодировать. Из какого байтового представления имена файлов кодируются в URI encoding? В каком месте в libxslt происходит кодирование? Автор не высказывал сомнений в безопасности раскодирования, он просто забил на
баг репорт в рассылке.
В libxml2-2.6.24 используется xmlURIUnescapeString для доступа к файлу, см.
ниже. Почему она не используется при доступе к файлу в libxslt ? Насколько я
понимаю, семантика там идентичная.
/libxslt/transform.c
./xmlIO.c-772-/**
./xmlIO.c-773- * xmlFileOpen:
./xmlIO.c-774- * @filename: the URI for matching
./xmlIO.c-775- *
./xmlIO.c-776- * Wrapper around xmlFileOpen_real that try it with an unescaped
./xmlIO.c-777- * version of @filename, if this fails fallback to @filename
./xmlIO.c-778- *
./xmlIO.c-779- * Returns a handler or NULL in case or failure
./xmlIO.c-780- */
./xmlIO.c-781-void *
./xmlIO.c-782-xmlFileOpen (const char *filename) {
./xmlIO.c-783- char *unescaped;
./xmlIO.c-784- void *retval;
./xmlIO.c-785-
./xmlIO.c:786: unescaped = xmlURIUnescapeString(filename, 0, NULL);
./xmlIO.c-787- if (unescaped != NULL) {
./xmlIO.c-788- retval = xmlFileOpen_real(unescaped);
./xmlIO.c-789- xmlFree(unescaped);
./xmlIO.c-790- } else {
./xmlIO.c-791- retval = xmlFileOpen_real(filename);
./xmlIO.c-792- }
./xmlIO.c-793- return retval;
./xmlIO.c-794-}
Обсуждения проблемы на тему чтения из файла:
http://mail.gnome.org/archives/xslt/2001-July/msg00026.html
http://mail.gnome.org/archives/xml/2005-August/msg00019.html
Обсуждение на тему exsl:document сходу не нашёл.
В любом случае, при записи в файл нужно открывать файл, а не пытаться открыть
URI. Проблему с отсутствием явной кодировки я понимаю, и есть мнение, что
filename -> escape -> unescape даёт filename независимо от кодировки, потому что
функции кодирования/декодирования работают побайтно (AFAIK). Мнение
подтверждается тем фактом, что с приложенным патчем у меня работает нормально
запись в файлы с пробелами в именах. Под win32 и linux.
Запись в файлы с именами в latin1 тоже работает.
В предыдущий комментарий строка: libxslt/transform.c попала по ошибке. Да, поскольку в <exsl:document> именно URI, то его нужно раскодировать. Сделаю. Как насчет доработать патч на предмет избавления от утечки памяти? Первый буфер, на который указывает filename, после преобразования просто теряется. Я могу это сделать сам, но позже. Через несколько строк в коде после предлагаемого изменения вызывается xsltCheckWrite, которая, судя по документации, тоже хочет URI. И outputFile в xsltTransformContext должен быть URI. Наверное, перекодировка должна происходить все-таки позже и уровнем ниже (т.к. должен сработать и xsltCheckWrite, и последующая запись). В существуюм виде патч применять воздержусь, нужно смотреть еще. Fixed in libxml2-2.6.26-alt2 and libxslt-1.1.17-alt1. See the GNOME bug for details. Ваш патч впечатляет, спасибо! |
При сборке стилями DocBook XSL формата HTML dir и указании 'base.dir' 'путь с национальными символами или пробелом' xsltproc сначала кодирует нац. символы и пробел в %nn, а при создании файлов не раскодирует их обратно. Есть предложение собирать libxslt с таким патчем: diff -ur libxslt-1.1.15.orig/libxslt/transform.c libxslt-1.1.15/libxslt/transform.c --- libxslt-1.1.15.orig/libxslt/transform.c 2005-08-31 14:47:15 +0400 +++ libxslt-1.1.15/libxslt/transform.c 2006-04-06 15:07:00 +0400 @@ -2060,6 +2060,11 @@ } /* + * Unescape filename for non ASCII world + */ + filename = (xmlChar *) xmlURIUnescapeString((const char *)filename,0,NULL); + + /* * Security checking: can we write to this resource */ if (ctxt->sec != NULL) { См. http://bugzilla.gnome.org/show_bug.cgi?id=337486 Правда, автору говорили о проблеме ещё год назад, и похоже, что он в очередной раз упёрся рогом.