web-dev-qa-db-ja.com

Androidリソースで<!ENTITYを使用しようとすると、エラーが発生しました:「エンティティは参照されましたが、宣言されていません。」

私はこのソリューションに従って、文字列リソースファイルでエネティを使用しています。

AndroidリソースXMLファイルで直接文字列置換を行うことは可能ですか?

リソースツリーで外部ファイルを使用しています:/res/raw/entities.dtd、その内容:

<!ENTITY ent_devicename "MyDeviceName">

の中に 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プロジェクト、分離されたファイルにエンティティ宣言があります。

[〜#〜] update [〜#〜]OK、このw3schoolsリンクにもっと注意を払えば:

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

あなたは解決策を見ます:

外部entities.dtdファイルには

<!ENTITY ent_devicename "MyDeviceName">

次に、新しい文字列リソースresource:

<?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はエンティティ値を無視するようです(空の文字列を使用します)。したがって、問題は解決されません!

お知らせ下さい!

20
Seraphim's

TL; DRこの機能はAndroid Studio。から削除されました。バグレポートを参照してください こちら =。

Android Studioで一度にXML外部エンティティがサポートされていたようです。また、Android Studioは現在、エディタ以降、外部エンティティをサポートしているはずです。文句を言わないXMLの基本的な処理は、実際には「参照されているが宣言されていない」エラーを発生させ、期待どおりに組み込みを行いません。

Android Studioが外部エンティティを破棄すること)への明示的な参照は見つかりませんでしたが、発見された脆弱性のため、それは理にかなっています。 XXE攻撃からのデータ露出の影響を受けやすいAndroid開発者 および セキュリティの記述 を参照してください。

外部エンティティへのアクセスがなんらかの理由でゲートされている可能性もありますが、Android Studioがそうである場合、Studioがより役立つと思います。機能が単に削除された可能性が高いです脆弱性に。

ちなみに、私は他の答えを試してみましたが、私には運がありませんでした-同じエラーだけです。

編集:

XXEの脆弱性に対処するJetBrainsについて説明している Medium post に遭遇しました。

2番目の編集

バグトラッカーで無効化の 参照 を見つけました。

これはセキュリティ上の理由で無効になっている可能性があります。解決する前に完全な分析が必要であり、3.2にパントします

そして

これは、セキュリティ上の理由から(XXE攻撃を防止するため)Change-Id:I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4で実際に無効になっています。

ステータスは「修正意図の動作ではありません」です。セキュリティ上の理由で機能が無効になっていることを示すエラーメッセージを出力するようにStudioが変更されていたら、良かったでしょう。

12
Cheticamp

この質問への回答/コメントが役に立たないという履歴があるので、一度に簡略化して1ステップずつ近づいていきましょう。以下に示す更新されたエンティティ名を使用し、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>

手順1を実行できるかどうかをコメントで明示的にお知らせください。

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>

entities.entで定義されたエンティティを共有できるようになります。

このステップでは、内部エンティティと外部エンティティのエンティティ名を再利用するしないように注意し、複雑さを追加しないでください。別のディレクトリの場所。 entity.entとstring.xmlの両方を同じディレクトリに配置します。 (これは、期待される機能を確立した後で緩和できます。)

繰り返しになりますが、ステップ2を機能させることができるかどうかコメントでお知らせください。

2
kjhughes

外部エンティティをインポートできないと思います( proof1proof2 )。ここが唯一の方法です。

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

または、Java/Kotlinでプレースホルダーを解決せずにXMLファイルで解決することを好む場合は、私が作成したこの小さなライブラリーを使用できます。 https://github.com/LikeTheSalad/Android-string -reference これにより、次のようなことが可能になります。

<resources>
    <string name="devicename">MyDeviceName</string>
    <string name="template_name">The name is ${devicename}</string>
</resources>

次に、プロジェクトを作成/ビルドすると、新しいファイルが次のように生成されます。

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

上記のリポジトリの詳細。

0
César Muñoz