Попытка использовать <!ENTITY in ANDROID resources with error: "The entity was referenced, but not declared."</div>

Я следую этому решению, чтобы использовать enetities в файле строковых ресурсов:

Можно ли напрямую выполнить замену строк в XML файлах ресурсов Android?

Я использую внешний файл в дереве ресурсов: /res/raw/entities.dtd, его содержимое:

<!ENTITY ent_devicename "MyDeviceName">

В string.xml ресурсов string.xml:

<!DOCTYPE resources [
    <!ENTITY % ent_devicename SYSTEM "../raw/entities.dtd">
    %ent_devicename;
]>

<resources>
    <string name="name">The name is &ent_devicename;</string>
</resources>

но я получаю эту ошибку:

Сущность "ent_devicename" была указана, но не объявлена.

Как вы можете видеть, Android Studio распознает внешний файл сущности:

enter image description here

и субъект:

enter image description here

Может ли кто-нибудь предоставить полный правильный пример, чтобы все работало? Я имею в виду полный компилируемый проект Android Studio, с объявлениями сущностей в разделенном файле.

ОБНОВЛЕНИЕ Хорошо, если вы уделяете больше внимания этой ссылке w3schools:

https://www.w3schools.com/xml/xml_dtd_entities.asp

вы видите решение:

файлы external entities.dtd содержат

<!ENTITY ent_devicename "MyDeviceName">

то новый ресурс ресурса строки:

<?xml version="1.0" encoding="utf-8"?>

    <!DOCTYPE resources [
        <!ENTITY ent_devicename SYSTEM "../raw/entities.dtd">
        ]>

<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="Typos">
    <string name="ent_devicenamxxe2">&ent_devicename;</string>

Я изменил <!ENTITY % ent_devicename на <!ENTITY ent_devicename (не более%) Я удалил %ent_devicename;

Теперь он компилируется, но полученный APK, похоже, игнорирует значения сущности (использует пустую строку). Поэтому проблема не решена!

Дай мне знать!

Ответы

Ответ 1

TL; DR Эта функция была удалена из Android Studio. См. Отчет об ошибке здесь.

Похоже, что внешние интерфейсы XML поддерживались одновременно в Android Studio. Мне также кажется, что Android Studio в настоящее время должна поддерживать внешние объекты, поскольку редактор не жалуется. Основная обработка XML на самом деле не делает включение, как ожидается, давая ошибку "ссылка, но не объявленная".

Хотя я не нашел явной ссылки на Android Studio, отказавшись от внешних объектов, это будет иметь смысл из-за уязвимости, которая была обнаружена. См. Android-разработчики, подверженные влиянию данных, с помощью атаки XXE и записи безопасности.

Также возможно, что доступ к внешним объектам теперь каким-то образом закрыт, но я думаю, что Android Studio будет более полезной, если это так. Более вероятно, что функциональность была просто удалена из-за уязвимости.

Кстати, я экспериментировал с другими ответами, и мне не повезло - такая же ошибка.

Редактировать:

Я просто наткнулся на средний пост, в котором обсуждаются проблемы JetBrains, затрагивающие уязвимость XXE.

Второе редактирование

Я нашел ссылку для отключения на трекер ошибок.

это может быть отключено по соображениям безопасности, оно требует полного анализа до разрешения, пренебрегая 3.2

а также

Это действительно было отключено по соображениям безопасности (предотвращение атак типа XXE) в Change-Id: I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4.

Это статус "не будет исправлять поведение". Было бы неплохо, если бы Studio была изменена, чтобы выпустить сообщение об ошибке, что средство было отключено по соображениям безопасности.

Ответ 2

Я боюсь, что импорт внешних объектов невозможен (доказательство1, доказательство2). Вот единственный способ.

<?xml version="1.0"?>
<!DOCTYPE resources [
    <!ENTITY value_a "Value A">
    <!ENTITY value_b "Value B">
    ]>

<resources>
    <string name="app_name">&value_a;</string>
    <string name="app_settings ">&value_b;</string>
</resources>

Ответ 3

Там история ответов/комментариев на этот вопрос не помогает вам, поэтому пусть упрощается и приближается к одному шагу за раз. Пожалуйста, используйте обновленные имена сущностей, которые я покажу ниже, и, пожалуйста, используйте один каталог как для файла XML, так и для файла с включенными объектами.

1. Установите, что ссылки на внутренние сущности работают.

string.xml

<!DOCTYPE resources [
  <!ENTITY devicename "MyDeviceName">
]>

<resources>
    <string name="name">The name is &devicename;</string>
</resources>

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

<resources>
    <string name="name">The name is MyDeviceName</string>
</resources>

Дайте мне знать в комментариях, можете ли вы сделать первый шаг работы.

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

entities.ent

<!ENTITY devicename "MyDeviceName">

string.xml

<!DOCTYPE resources [
    <!ENTITY % ext_entities SYSTEM "entities.ent">
    %ext_entities;
]>

<resources>
    <string name="name">The name is &devicename;</string>
</resources>

Для XML-приложения, использующего согласованный синтаксический анализатор XML, string.xml снова будет эквивалентен

<resources>
    <string name="name">The name is MyDeviceName</string>
</resources>

и теперь вы сможете делиться сущностями, определенными в entity.ent.

На этом шаге я прошу вас не заново использовать имена сущностей для внутренних и внешних объектов и что вы не добавляете никаких осложнений из-за различного расположения каталога; поместите оба объекта entity.ent и string.xml в тот же каталог. (Это может быть ослаблено позже, как только вы установите ожидаемую функциональность.)

Опять же, дайте мне знать в комментариях, можете ли вы сделать шаг 2 работать.