• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NaturalIntelligence / fast-xml-parser / 12317922166

13 Dec 2024 02:55PM UTC coverage: 98.212%. Remained the same
12317922166

Pull #699

github

web-flow
Merge ae43748a5 into 408290231
Pull Request #699: Fixes entity parsing when used in strict mode

804 of 863 branches covered (93.16%)

2746 of 2796 relevant lines covered (98.21%)

682647.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.31
/src/xmlparser/DocTypeReader.js
1
const util = require('../util');
4✔
2

3
//TODO: handle comments
4
function readDocType(xmlData, i){
5
    
6
    const entities = {};
52✔
7
    if( xmlData[i + 3] === 'O' &&
52!
8
         xmlData[i + 4] === 'C' &&
9
         xmlData[i + 5] === 'T' &&
10
         xmlData[i + 6] === 'Y' &&
11
         xmlData[i + 7] === 'P' &&
12
         xmlData[i + 8] === 'E')
13
    {    
14
        i = i+9;
52✔
15
        let angleBracketsCount = 1;
52✔
16
        let hasBody = false, comment = false;
52✔
17
        let exp = "";
52✔
18
        for(;i<xmlData.length;i++){
52✔
19
            if (xmlData[i] === '<' && !comment) { //Determine the tag type
3,344✔
20
                if( hasBody && isEntity(xmlData, i)){
92✔
21
                    i += 7; 
52✔
22
                    let entityName, val;
23
                    [entityName, val,i] = readEntityExp(xmlData,i+1);
52✔
24
                    if(val.indexOf("&") === -1) //Parameter entities are not supported
52✔
25
                        entities[ validateEntityName(entityName) ] = {
48✔
26
                            regx : RegExp( `&${entityName};`,"g"),
27
                            val: val
28
                        };
29
                }
30
                else if( hasBody && isElement(xmlData, i))  i += 8;//Not supported
40✔
31
                else if( hasBody && isAttlist(xmlData, i))  i += 8;//Not supported
28✔
32
                else if( hasBody && isNotation(xmlData, i)) i += 9;//Not supported
24✔
33
                else if( isComment)                         comment = true;
20!
34
                else                                        throw new Error("Invalid DOCTYPE");
×
35

36
                angleBracketsCount++;
88✔
37
                exp = "";
88✔
38
            } else if (xmlData[i] === '>') { //Read tag content
3,252✔
39
                if(comment){
136✔
40
                    if( xmlData[i - 1] === "-" && xmlData[i - 2] === "-"){
24✔
41
                        comment = false;
20✔
42
                        angleBracketsCount--;
20✔
43
                    }
44
                }else{
45
                    angleBracketsCount--;
112✔
46
                }
47
                if (angleBracketsCount === 0) {
136✔
48
                  break;
44✔
49
                }
50
            }else if( xmlData[i] === '['){
3,116✔
51
                hasBody = true;
40✔
52
            }else{
53
                exp += xmlData[i];
3,076✔
54
            }
55
        }
56
        if(angleBracketsCount !== 0){
48✔
57
            throw new Error(`Unclosed DOCTYPE`);
4✔
58
        }
59
    }else{
60
        throw new Error(`Invalid Tag instead of DOCTYPE`);
×
61
    }
62
    return {entities, i};
44✔
63
}
64

65
function readEntityExp(xmlData,i){
66
    //External entities are not supported
67
    //    <!ENTITY ext SYSTEM "http://normal-website.com" >
68

69
    //Parameter entities are not supported
70
    //    <!ENTITY entityname "&anotherElement;">
71

72
    //Internal entities are supported
73
    //    <!ENTITY entityname "replacement text">
74
    
75
    //read EntityName
76
    let entityName = "";
52✔
77
    for (; i < xmlData.length && (xmlData[i] !== "'" && xmlData[i] !== '"' ); i++) {
52✔
78
        // if(xmlData[i] === " ") continue;
79
        // else 
80
        entityName += xmlData[i];
396✔
81
    }
82
    entityName = entityName.trim();
52✔
83
    if(entityName.indexOf(" ") !== -1) throw new Error("External entites are not supported");
52!
84

85
    //read Entity Value
86
    const startChar = xmlData[i++];
52✔
87
    let val = ""
52✔
88
    for (; i < xmlData.length && xmlData[i] !== startChar ; i++) {
52✔
89
        val += xmlData[i];
2,064✔
90
    }
91
    return [entityName, val, i];
52✔
92
}
93

94
function isComment(xmlData, i){
95
    if(xmlData[i+1] === '!' &&
×
96
    xmlData[i+2] === '-' &&
97
    xmlData[i+3] === '-') return true
×
98
    return false
×
99
}
100
function isEntity(xmlData, i){
101
    if(xmlData[i+1] === '!' &&
92✔
102
    xmlData[i+2] === 'E' &&
103
    xmlData[i+3] === 'N' &&
104
    xmlData[i+4] === 'T' &&
105
    xmlData[i+5] === 'I' &&
106
    xmlData[i+6] === 'T' &&
107
    xmlData[i+7] === 'Y') return true
52✔
108
    return false
40✔
109
}
110
function isElement(xmlData, i){
111
    if(xmlData[i+1] === '!' &&
40✔
112
    xmlData[i+2] === 'E' &&
113
    xmlData[i+3] === 'L' &&
114
    xmlData[i+4] === 'E' &&
115
    xmlData[i+5] === 'M' &&
116
    xmlData[i+6] === 'E' &&
117
    xmlData[i+7] === 'N' &&
118
    xmlData[i+8] === 'T') return true
12✔
119
    return false
28✔
120
}
121

122
function isAttlist(xmlData, i){
123
    if(xmlData[i+1] === '!' &&
28✔
124
    xmlData[i+2] === 'A' &&
125
    xmlData[i+3] === 'T' &&
126
    xmlData[i+4] === 'T' &&
127
    xmlData[i+5] === 'L' &&
128
    xmlData[i+6] === 'I' &&
129
    xmlData[i+7] === 'S' &&
130
    xmlData[i+8] === 'T') return true
4✔
131
    return false
24✔
132
}
133
function isNotation(xmlData, i){
134
    if(xmlData[i+1] === '!' &&
24✔
135
    xmlData[i+2] === 'N' &&
136
    xmlData[i+3] === 'O' &&
137
    xmlData[i+4] === 'T' &&
138
    xmlData[i+5] === 'A' &&
139
    xmlData[i+6] === 'T' &&
140
    xmlData[i+7] === 'I' &&
141
    xmlData[i+8] === 'O' &&
142
    xmlData[i+9] === 'N') return true
4✔
143
    return false
20✔
144
}
145

146
function validateEntityName(name){
147
    if (util.isName(name))
48✔
148
        return name;
44✔
149
    else
150
        throw new Error(`Invalid entity name ${name}`);
4✔
151
}
152

153
module.exports = readDocType;
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc