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

NaturalIntelligence / fast-xml-parser / 13817442089

12 Mar 2025 05:13PM CUT coverage: 98.946%. Remained the same
13817442089

Pull #734

github

web-flow
Merge 4a6d4de32 into af4f1d2d4
Pull Request #734: [WIP] ci: build with Node 18.x

1087 of 1120 branches covered (97.05%)

8640 of 8732 relevant lines covered (98.95%)

510597.48 hits per line

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

94.04
/src/xmlparser/DocTypeReader.js
1
import {isName} from '../util.js';
5✔
2

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

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

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

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

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

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

5✔
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){
115✔
101
    if(xmlData[i+1] === '!' &&
115✔
102
    xmlData[i+2] === 'E' &&
115✔
103
    xmlData[i+3] === 'N' &&
115✔
104
    xmlData[i+4] === 'T' &&
115✔
105
    xmlData[i+5] === 'I' &&
115✔
106
    xmlData[i+6] === 'T' &&
115✔
107
    xmlData[i+7] === 'Y') return true
115✔
108
    return false
50✔
109
}
115✔
110
function isElement(xmlData, i){
50✔
111
    if(xmlData[i+1] === '!' &&
50✔
112
    xmlData[i+2] === 'E' &&
50✔
113
    xmlData[i+3] === 'L' &&
50✔
114
    xmlData[i+4] === 'E' &&
50✔
115
    xmlData[i+5] === 'M' &&
50✔
116
    xmlData[i+6] === 'E' &&
50✔
117
    xmlData[i+7] === 'N' &&
50✔
118
    xmlData[i+8] === 'T') return true
50✔
119
    return false
35✔
120
}
50✔
121

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

5✔
146
function validateEntityName(name){
60✔
147
    if (isName(name))
60✔
148
        return name;
60✔
149
    else
5✔
150
        throw new Error(`Invalid entity name ${name}`);
5✔
151
}
60✔
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