web-dev-qa-db-fra.com

Essayer d'utiliser <! ENTITY dans les ressources Android avec l'erreur suivante: "L'entité a été référencée, mais non déclarée."

Je suis cette solution pour utiliser des ressources dans mon fichier de ressources de chaîne:

Est-il possible de faire la substitution de chaîne dans les fichiers XML de ressources Android directement?

J'utilise un fichier externe dans l'arborescence des ressources: /res/raw/entities.dtd, son contenu:

<!ENTITY ent_devicename "MyDeviceName">

Dans le fichier de ressources string.xml:

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

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

mais j'obtiens cette erreur:

L'entité "ent_devicename" a été référencée mais non déclarée.

Comme vous pouvez le voir, Android Studio reconnaît le fichier d'entité externe:

 enter image description here

et l'entité:

 enter image description here

Quelqu'un peut-il fournir un exemple complet pour que les choses fonctionnent? Je veux dire un projet Android Studio compilable complet, avec des déclarations d'entités dans un fichier séparé.

UPDATE Ok, si vous faites plus attention à ce lien dans w3schools:

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

vous voyez la solution:

les fichiers entities.dtd externes contiennent

<!ENTITY ent_devicename "MyDeviceName">

puis la nouvelle ressource de chaîne:

<?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>

J'ai changé <!ENTITY % ent_devicename en <!ENTITY ent_devicename (pas plus de%) J'ai supprimé %ent_devicename;

Maintenant, il compile mais l'APK résultant semble ignorer les valeurs d'entité (utilise une chaîne vide). Donc, le problème n'est pas résolu!

Faites le moi savoir!

17
Seraphim's

TL; DR Cette fonctionnalité a été supprimée de Android Studio. Voir le rapport de bogue ici .

Il semble que les entités externes XML aient été prises en charge à la fois sur Android Studio. Il me semble également qu'Android Studio devrait actuellement prendre en charge des entités externes, car l'éditeur ne se plaint pas. Le traitement sous-jacent du XML ne fait pas l'inclusion comme prévu, donnant l'erreur "référencée mais non déclarée".

Bien que je n’ai pas trouvé de référence explicite à Android Studio qui abandonne des entités externes, cela aurait du sens en raison d’une vulnérabilité qui a été découverte. Voir Développeurs Android sensibles à l’exposition de données à partir de XXE Attack et le rédaction de sécurité .

Il est également possible que l'accès aux entités externes soit maintenant bloqué, mais je pense qu'Android Studio serait plus utile si c'était le cas. Il est plus probable que la fonctionnalité ait été simplement supprimée en raison de la vulnérabilité.

A propos, j'ai expérimenté les autres réponses et je n'ai pas eu de chance - juste la même erreur.

Modifier:

Je viens de tomber sur un message moyen qui traite de JetBrains qui traite de la vulnérabilité XXE.

Deuxième édition

J'ai trouvé un référence pour la désactivation sur le traqueur de bogues.

ceci peut avoir été désactivé pour des raisons de sécurité, une analyse complète est nécessaire avant la résolution, allant jusqu'à 3.2

et 

Ceci a bien été désactivé pour des raisons de sécurité (prévention des attaques XXE) dans Change-Id: I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4.

Son statut est "ne corrige pas le comportement souhaité". Cela aurait été agréable si Studio avait été modifié pour émettre un message d'erreur indiquant que l'installation était désactivée pour des raisons de sécurité.

9
Cheticamp

Il y a un historique de réponses/commentaires à cette question qui ne vous aide pas, alors simplifions-nous et abordons une étape à la fois. Veuillez utiliser les noms d’entités mis à jour que je montre ci-dessous et utiliser un seul répertoire pour le fichier XML et le fichier d’entités inclus.

1. Établissez que les références d'entités internes fonctionnent.

string.xml

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

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

Vérifiez que cela fonctionne comme prévu: après que les applications aient analysé ce fichier XML, il devrait être équivalent à ce fichier XML:

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

Laissez-moi savoir explicitement dans les commentaires si vous êtes capable de faire fonctionner l'étape 1.

2. Ajoutez le niveau supplémentaire d'indirection, si nécessaire.

entités.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>

Pour une application XML qui utilise un analyseur XML conforme, string.xml sera à nouveau équivalent à 

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

et vous pourrez maintenant partager les entités définies dans entity.ent .

Pour cette étape, je vous demande de veiller à pas à réutiliser les noms d'entité pour les entités internes et externes et de ne pas ajouter de complications en raison d'un emplacement de répertoire différent; Placez les deux entités.ent et string.xml dans le même répertoire. (Cela peut être relâché plus tard une fois que vous avez défini la fonctionnalité attendue.)

Encore une fois, laissez-moi savoir dans les commentaires si vous êtes capable de faire fonctionner l'étape 2.

2
kjhughes

Je crains d'importer des entités externes n'est pas possible ( proof1 , proof2 ). Voici le seul moyen.

<?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>
1
deadfish