@@ -60,20 +60,20 @@ exports.validate = function(xmlData){
6060 attrStr += xmlData [ i ] ;
6161 }
6262 if ( startChar !== "" ) return false ; //Unclosed quote
63- attrStr = attrStr . trim ( ) ;
63+ // attrStr = attrStr.trim();
6464 //console.log(attrStr, attrStr);
6565
6666 if ( attrStr [ attrStr . length - 1 ] === "/" ) { //self closing tag
67- attrStr = attrStr . substring ( 0 , attrStr . length - 2 ) ;
68-
67+ attrStr = attrStr . substring ( 0 , attrStr . length - 1 ) ;
68+ //console.log(attrStr);
6969 if ( ! validateAttributeString ( attrStr ) ) {
7070 return false ;
7171 } else {
7272
7373 continue ;
7474 }
7575 } else if ( closingTag ) {
76- if ( attrStr . length > 0 ) {
76+ if ( attrStr . trim ( ) . length > 0 ) {
7777 return false ;
7878 //throw new Error("XML validation error: closing tag should not have any attribute");
7979 } else {
@@ -148,60 +148,52 @@ function readCommentAndCDATA(xmlData,i){
148148
149149 return i ;
150150}
151- //attr, ="sd", a="amit's", a="sd"b="saf",
151+
152+ /**
153+ * Select all the attributes whether valid or invalid.
154+ */
155+ var validAttrStrRegxp = new RegExp ( "(\\s*)([^\\s=]+)\\s*(=)?(\\s*(['\"])((.|\\n)*?)\\5)?" , "g" ) ;
156+
157+ //attr, ="sd", a="amit's", a="sd"b="saf", ab cd=""
158+
152159function validateAttributeString ( attrStr ) {
153- var attrNames = [ ] ;
154- for ( var i = 0 ; i < attrStr . length ; i ++ ) {
155- var startChar = "" ;
156- //read attribute name
157- var attrName = "" ;
158- for ( ; i < attrStr . length && attrStr [ i ] !== "=" ; i ++ ) {
159- attrName += attrStr [ i ] ;
160- }
161- //validate attrName
162- attrName = attrName . trim ( ) ;
160+ //console.log("start:"+attrStr+":end");
163161
162+ //if(attrStr.trim().length === 0) return true; //empty string
164163
164+ var matches = util . getAllMatches ( attrStr , validAttrStrRegxp ) ;
165+ var attrNames = [ ] ;
165166
166- if ( ! attrNames . hasOwnProperty ( attrName ) ) {
167- attrNames [ attrName ] = 1 ;
168- } else {
167+
168+ for ( var i = 0 ; i < matches . length ; i ++ ) {
169+ //console.log(matches[i]);
170+
171+ if ( matches [ i ] [ 1 ] . length === 0 ) { //nospace before attribute name: a="sd"b="saf"
172+ return false ;
173+ } else if ( matches [ i ] [ 3 ] === undefined ) { //independent attribute: ab
174+ return false ;
175+ } else if ( matches [ i ] [ 6 ] === undefined ) { //attribute without value: ab=
169176 return false ;
170177 }
178+ attrName = matches [ i ] [ 2 ] ;
171179 if ( ! validateAttrName ( attrName ) ) {
180+ //console.log("seems invalid");
172181 return false ;
173182 }
174- i ++ ;
175-
176- //skip whitespaces
177- for ( ; i < attrStr . length
178- && ( attrStr [ i ] === " "
179- || attrStr [ i ] === "\t" ) ; i ++ ) ;
180-
181- //read attribute value
182- startChar = attrStr [ i ++ ] ;
183-
184- var attrVal = "" ;
185- for ( ; i < attrStr . length && attrStr [ i ] !== startChar ; i ++ ) {
186- attrVal += attrStr [ i ] ;
187- }
188-
189- //validate attrVal
190-
191- if ( startChar !== "" ) {
192- i ++ ;
193- if ( i < attrStr . length && ( attrStr [ i ] !== " " && attrStr [ i ] !== "\t" ) ) { //when no spce between 2 attributes : a="sd"b="saf"
194- return false ;
195- }
196- startChar = "" ;
183+ if ( ! attrNames . hasOwnProperty ( attrName ) ) { //check for duplicate attribute.
184+ attrNames [ attrName ] = 1 ;
185+ } else {
186+ return false ;
197187 }
198188 }
199189
200190 return true ;
191+
201192}
202193
203194var validAttrRegxp = new RegExp ( "^[_a-zA-Z][\\w\\-\\.\\:]*$" ) ;
204195
196+
205197function validateAttrName ( attrName ) {
206198 return util . doesMatch ( attrName , validAttrRegxp ) ;
207199}
0 commit comments