@@ -22,7 +22,7 @@ export default function readDocType(xmlData, i){
2222                    let  entityName ,  val ; 
2323                    [ entityName ,  val , i ]  =  readEntityExp ( xmlData , i + 1 ) ; 
2424                    if ( val . indexOf ( "&" )  ===  - 1 )  //Parameter entities are not supported 
25-                         entities [  validateEntityName ( entityName )  ]  =  { 
25+                         entities [  entityName  ]  =  { 
2626                            regx  : RegExp (  `&${ entityName }  ;` , "g" ) , 
2727                            val : val 
2828                        } ; 
@@ -62,7 +62,14 @@ export default function readDocType(xmlData, i){
6262    return  { entities,  i} ; 
6363} 
6464
65- function  readEntityExp ( xmlData , i ) { 
65+ const  skipWhitespace  =  ( data ,  index )  =>  { 
66+     while  ( index  <  data . length  &&  / \s / . test ( data [ index ] ) )  { 
67+         index ++ ; 
68+     } 
69+     return  index ; 
70+ } ; 
71+ 
72+ function  readEntityExp ( xmlData ,  i )  {     
6673    //External entities are not supported 
6774    //    <!ENTITY ext SYSTEM "http://normal-website.com" > 
6875
@@ -71,26 +78,53 @@ function readEntityExp(xmlData,i){
7178
7279    //Internal entities are supported 
7380    //    <!ENTITY entityname "replacement text"> 
74-     
75-     //read EntityName 
81+ 
82+     // Skip leading whitespace after <!ENTITY 
83+     i  =  skipWhitespace ( xmlData ,  i ) ; 
84+ 
85+     // Read entity name 
7686    let  entityName  =  "" ; 
77-     for  ( ;  i  <  xmlData . length  &&  ( xmlData [ i ]  !==  "'"  &&  xmlData [ i ]  !==  '"'  ) ;  i ++ )  { 
78-         // if(xmlData[i] === " ") continue; 
79-         // else  
87+     while  ( i  <  xmlData . length  &&  ! / \s / . test ( xmlData [ i ] )  &&  xmlData [ i ]  !==  '"'  &&  xmlData [ i ]  !==  "'" )  { 
8088        entityName  +=  xmlData [ i ] ; 
89+         i ++ ; 
8190    } 
82-     entityName  =  entityName . trim ( ) ; 
83-     if ( entityName . indexOf ( " " )  !==  - 1 )  throw  new  Error ( "External entites are not supported" ) ; 
84- 
85-     //read Entity Value 
86-     const  startChar  =  xmlData [ i ++ ] ; 
87-     let  val  =  "" 
88-     for  ( ;  i  <  xmlData . length  &&  xmlData [ i ]  !==  startChar  ;  i ++ )  { 
89-         val  +=  xmlData [ i ] ; 
91+ 
92+     // Validate entity name 
93+     if  ( ! validateEntityName ( entityName ) )  { 
94+         throw  new  Error ( `Invalid entity name: "${ entityName }  "` ) ; 
95+     } 
96+ 
97+     // Skip whitespace after entity name 
98+     i  =  skipWhitespace ( xmlData ,  i ) ; 
99+ 
100+     // Check for unsupported constructs (external entities or parameter entities) 
101+     if  ( xmlData . substring ( i ,  i  +  6 ) . toUpperCase ( )  ===  "SYSTEM" )  { 
102+         throw  new  Error ( "External entities are not supported" ) ; 
103+     } else  if  ( xmlData [ i ]  ===  "%" )  { 
104+         throw  new  Error ( "Parameter entities are not supported" ) ; 
90105    } 
91-     return  [ entityName ,  val ,  i ] ; 
106+ 
107+     // Read entity value (internal entity) 
108+     const  quoteChar  =  xmlData [ i ] ; 
109+     if  ( quoteChar  !==  '"'  &&  quoteChar  !==  "'" )  { 
110+         throw  new  Error ( `Expected quoted string, found "${ quoteChar }  "` ) ; 
111+     } 
112+     i ++ ; 
113+ 
114+     let  entityValue  =  "" ; 
115+     while  ( i  <  xmlData . length  &&  xmlData [ i ]  !==  quoteChar )  { 
116+         entityValue  +=  xmlData [ i ] ; 
117+         i ++ ; 
118+     } 
119+ 
120+     if  ( xmlData [ i ]  !==  quoteChar )  { 
121+         throw  new  Error ( "Unterminated entity value" ) ; 
122+     } 
123+ 
124+     return  [ entityName ,  entityValue ,  i  ] ; 
92125} 
93126
127+ 
94128function  isComment ( xmlData ,  i ) { 
95129    if ( xmlData [ i + 1 ]  ===  '!'  && 
96130    xmlData [ i + 2 ]  ===  '-'  && 
0 commit comments