Trying to use <!ENTITY in ANDROID resources with error: “The entity was referenced, but not declared.”

后端 未结 4 750
清酒与你
清酒与你 2020-12-09 16:42

I\'m following this solution to use enetities in my string resource file:

Is it possible to do string substitution in Android resource XML files directly?

I\

相关标签:
4条回答
  • 2020-12-09 16:59

    TL;DR This feature has been removed from Android Studio. See the bug report here.

    It looks like XML External Entities were supported at one time on Android Studio. It also looks to me like Android Studio currently should be supporting external entities since the editor doesn't complain The underlying processing of the XML doesn't actually do the inclusion as expected giving the "referenced but not declared" error.

    Although I have not found an explicit reference to Android Studio abandoning external entities, it would make sense due to a vulnerability that was uncovered. See Android Developers Susceptible to Data Exposure from XXE Attack and the security write-up.

    It is also possible that access to external entities are now gated somehow, but I think that Android Studio would be more helpful if that is the case. It is more likely that the functionality was just removed due to the vulnerability.

    By the way, I have experimented with the other answers and I have had no luck - just the same error.

    Edit:

    I just came across a Medium post that discusses JetBrains addressing the XXE vulnerability.

    Second edit

    I found a reference for the disablement on the bug tracker.

    this may have been disabled for security reason, it requires complete analysis before resolution, punting to 3.2

    and

    This was indeed disabled for security reasons (preventing XXE attacks) in Change-Id: I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4.

    It's status is "won't fix-intended behavior." It would have been nice if Studio had been changed to emit an error message that the facility was disabled for security reasons.

    0 讨论(0)
  • 2020-12-09 17:00

    Alternatively, if you still prefer avoiding resolving placeholders on Java/Kotlin and rather get them resolved in the XML files, then you could use this small library I created: https://github.com/LikeTheSalad/android-string-reference which will allow you to do something like this:

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

    And then, you make/build the project, and a new file will be generated with:

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

    More info on the repo provided above.

    0 讨论(0)
  • 2020-12-09 17:03

    I am afraid importing external entities is not possible (proof1,proof2). Here is the only way.

    <?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>
    
    0 讨论(0)
  • 2020-12-09 17:09

    There's a history of answers/comments to this question not helping you, so let's simplify and approach one step at a time. Please use the updated entity names I show below, and please use a single directory for both the XML file and the included entities file.

    1. Establish that internal entity references are working.

    string.xml

    <!DOCTYPE resources [
      <!ENTITY devicename "MyDeviceName">
    ]>
    
    <resources>
        <string name="name">The name is &devicename;</string>
    </resources>
    

    Verify that this works as expected: After applications parse this XML file, it should be equivalent to this XML file:

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

    Let me know explicitly in the comments whether you are able to get step 1 working.

    2. Add the extra level of indirection, if needed.

    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>
    

    To an XML application that uses a conforming XML parser, string.xml will again be equivalent to

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

    and you will now be able to share the entities defined in entities.ent.

    For this step I ask that you take care not to re-use the entity names for the internal and external entities and that you not add any complications due to different directory location; place both entities.ent and string.xml in the same directory. (This can be relaxed later once you establish the expected functionality.)

    Again, let me know in the comments whether you are able to get step 2 working.

    0 讨论(0)
提交回复
热议问题