@@ -158,6 +158,9 @@ module Private
158158 DEFAULT_ENTITIES_PATTERNS [ term ] = /&#{ term } ;/
159159 end
160160 XML_PREFIXED_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
161+ EXTERNAL_ID_PUBLIC_PATTERN = /\s +#{ PUBIDLITERAL } \s +#{ SYSTEMLITERAL } /um
162+ EXTERNAL_ID_SYSTEM_PATTERN = /\s +#{ SYSTEMLITERAL } /um
163+ PUBLIC_ID_PATTERN = /\s +#{ PUBIDLITERAL } /um
161164 end
162165 private_constant :Private
163166
@@ -307,7 +310,6 @@ def pull_event
307310 @source . ensure_buffer
308311 else
309312 id = parse_id ( base_error_message ,
310- accept_external_id : true ,
311313 accept_public_id : false )
312314 if id [ 0 ] == "SYSTEM"
313315 # For backward compatibility
@@ -409,7 +411,6 @@ def pull_event
409411 end
410412 name = parse_name ( base_error_message )
411413 id = parse_id ( base_error_message ,
412- accept_external_id : true ,
413414 accept_public_id : true )
414415 @source . skip_spaces
415416 unless @source . match? ( ">" , true )
@@ -667,68 +668,41 @@ def parse_name(base_error_message)
667668 end
668669
669670 def parse_id ( base_error_message ,
670- accept_external_id :,
671671 accept_public_id :)
672- if accept_external_id and ( md = @source . match ( EXTERNAL_ID_PUBLIC , true ) )
673- pubid = system = nil
674- pubid_literal = md [ 1 ]
675- pubid = pubid_literal [ 1 ..-2 ] if pubid_literal # Remove quote
676- system_literal = md [ 2 ]
677- system = system_literal [ 1 ..-2 ] if system_literal # Remove quote
678- [ "PUBLIC" , pubid , system ]
679- elsif accept_public_id and ( md = @source . match ( PUBLIC_ID , true ) )
680- pubid = system = nil
681- pubid_literal = md [ 1 ]
682- pubid = pubid_literal [ 1 ..-2 ] if pubid_literal # Remove quote
683- [ "PUBLIC" , pubid , nil ]
684- elsif accept_external_id and ( md = @source . match ( EXTERNAL_ID_SYSTEM , true ) )
685- system = nil
686- system_literal = md [ 1 ]
687- system = system_literal [ 1 ..-2 ] if system_literal # Remove quote
688- [ "SYSTEM" , nil , system ]
689- else
690- details = parse_id_invalid_details ( accept_external_id : accept_external_id ,
691- accept_public_id : accept_public_id )
692- message = "#{ base_error_message } : #{ details } "
693- raise REXML ::ParseException . new ( message , @source )
694- end
695- end
696-
697- def parse_id_invalid_details ( accept_external_id :,
698- accept_public_id :)
699- public = /\A \s *PUBLIC/um
700- system = /\A \s *SYSTEM/um
701- if ( accept_external_id or accept_public_id ) and @source . match? ( /#{ public } /um )
702- if @source . match? ( /#{ public } (?:\s +[^'"]|\s *[\[ >])/um )
703- return "public ID literal is missing"
704- end
705- unless @source . match? ( /#{ public } \s +#{ PUBIDLITERAL } /um )
706- return "invalid public ID literal"
707- end
708- if accept_public_id
709- if @source . match? ( /#{ public } \s +#{ PUBIDLITERAL } \s +[^'"]/um )
710- return "system ID literal is missing"
711- end
712- unless @source . match? ( /#{ public } \s +#{ PUBIDLITERAL } \s +#{ SYSTEMLITERAL } /um )
713- return "invalid system literal"
714- end
715- "garbage after system literal"
672+ @source . skip_spaces
673+ if @source . match? ( "PUBLIC" , true )
674+ if ( md = @source . match ( Private ::EXTERNAL_ID_PUBLIC_PATTERN , true ) )
675+ pubid = system = nil
676+ pubid_literal = md [ 1 ]
677+ pubid = pubid_literal [ 1 ..-2 ] if pubid_literal # Remove quote
678+ system_literal = md [ 2 ]
679+ system = system_literal [ 1 ..-2 ] if system_literal # Remove quote
680+ [ "PUBLIC" , pubid , system ]
681+ elsif accept_public_id and ( md = @source . match ( Private ::PUBLIC_ID_PATTERN , true ) )
682+ pubid = system = nil
683+ pubid_literal = md [ 1 ]
684+ pubid = pubid_literal [ 1 ..-2 ] if pubid_literal # Remove quote
685+ [ "PUBLIC" , pubid , nil ]
686+ elsif @source . match? ( /(?:\s +[^'"]|\s *[\[ >])/um )
687+ raise REXML ::ParseException . new ( "#{ base_error_message } : public ID literal is missing" , @source )
688+ elsif !@source . match? ( Private ::PUBLIC_ID_PATTERN )
689+ raise REXML ::ParseException . new ( "#{ base_error_message } : invalid public ID literal" , @source )
716690 else
717- " garbage after public ID literal"
691+ raise REXML :: ParseException . new ( " #{ base_error_message } : garbage after public ID literal", @source )
718692 end
719- elsif accept_external_id and @source . match? ( /#{ system } /um )
720- if @source . match? ( /#{ system } (?:\s +[^'"]|\s *[\[ >])/um )
721- return "system literal is missing"
722- end
723- unless @source . match? ( /#{ system } \s +#{ SYSTEMLITERAL } /um )
724- return "invalid system literal"
693+ elsif @source . match? ( "SYSTEM" , true )
694+ if ( md = @source . match ( Private ::EXTERNAL_ID_SYSTEM_PATTERN , true ) )
695+ system = nil
696+ system_literal = md [ 1 ]
697+ system = system_literal [ 1 ..-2 ] if system_literal # Remove quote
698+ [ "SYSTEM" , nil , system ]
699+ elsif @source . match? ( /(?:\s +[^'"]|\s *[\[ >])/um )
700+ raise REXML ::ParseException . new ( "#{ base_error_message } : system literal is missing" , @source )
701+ else
702+ raise REXML ::ParseException . new ( "#{ base_error_message } : invalid system literal" , @source )
725703 end
726- "garbage after system literal"
727704 else
728- unless @source . match? ( /\A \s *(?:PUBLIC|SYSTEM)\s /um )
729- return "invalid ID type"
730- end
731- "ID type is missing"
705+ raise REXML ::ParseException . new ( "#{ base_error_message } : invalid ID type" , @source )
732706 end
733707 end
734708
0 commit comments