Commits

Shlomi Fish committed ee28185

Handle a non-closing tag gracefully.

Comments (0)

Files changed (5)

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/Err.pm

 use Exception::Class
     (
         "XML::Grammar::Fiction::Err::Base",
+        "XML::Grammar::Fiction::Err::Base::WithOpenTag" =>
+        {
+            isa => "XML::Grammar::Fiction::Err::Base",
+            fields => [qw(opening_tag)],
+        },
         "XML::Grammar::Fiction::Err::Parse::TagsMismatch" =>
         {
-            isa => "XML::Grammar::Fiction::Err::Base",
+            isa => "XML::Grammar::Fiction::Err::Base::WithOpenTag",
             fields => [qw(opening_tag closing_tag)],
         },
         "XML::Grammar::Fiction::Err::Parse::LineError" =>
         {
             isa => "XML::Grammar::Fiction::Err::Parse::LineError",
         },
+        "XML::Grammar::Fiction::Err::Parse::TagNotClosedAtEOF" =>
+        {
+            isa => "XML::Grammar::Fiction::Err::Base::WithOpenTag",
+        },
     )
     ;
 1;

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/FictionBase/FromProto/Parser/LineIterator.pm

 
     $self->_curr_line_idx($self->_curr_line_idx()+1);
 
-    pos(${$self->curr_line_ref()}) = 0;
+    if (! $self->eof() ) {
+        pos(${$self->curr_line_ref()}) = 0;
+    }
 
     return $self->curr_line_ref();
 }

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/FictionBase/FromProto/Parser/XmlIterator.pm

 
     if ($self->eof() && $self->_no_events())
     {
-        Carp::confess (qq{Reached EOF.});
+        if (! $self->_tag_stack_is_empty() )
+        {
+            XML::Grammar::Fiction::Err::Parse::TagNotClosedAtEOF->throw(
+                error => "Tag not closed at EOF.",
+                opening_tag => $self->_top_tag(),
+            );
+        }
+        else
+        {
+            Carp::confess (qq{Reached EOF.});
+        }
     }
 
     return;

perl/modules/XML-Grammar-Fiction/t/screenplay/data/proto-text-invalid/non-terminated-desc.txt

+<s id="top">
+
+<s id="david_and_goliath">
+
+[David and Goliath are standing by each other.
+
+David is a red-head.
+
+Goliath is very tall.]
+
+David: I will kill you.
+
+Goliath: no way, you little idiot!
+
+David: yes way!
+
+++++: In the name of Allah, the merciful, I will show you the power of my
+sling.
+
+++++: I shall sling you and bing you till infinity.
+
+[David takes his sling.
+
+Goliath: I'm still waiting.
+

perl/modules/XML-Grammar-Fiction/t/screenplay/proto-text-invalid.t

 
 use Test::More;
 
-use Test::More tests => 1;
+use Test::More tests => 2;
 
 use XML::LibXML;
 
     return $contents;
 }
 
-my $grammar = XML::Grammar::Screenplay::FromProto->new({
+
+{
+    my $grammar = XML::Grammar::Screenplay::FromProto->new({
         parser_class => "XML::Grammar::Screenplay::FromProto::Parser::QnD",
     });
 
-eval {
-my $got_xml = $grammar->convert(
-    {
-        source =>
-        {
-            file => "t/screenplay/data/proto-text-invalid/inner-desc-inside-char-addressing.txt",
-        },
-    }
-);
-};
+    eval {
+        my $got_xml = $grammar->convert(
+            {
+                source =>
+                {
+                    file => "t/screenplay/data/proto-text-invalid/inner-desc-inside-char-addressing.txt",
+                },
+            }
+        );
+    };
 
-my $err = $@;
+    my $err = $@;
 
-# TEST
-like ($err, qr{inner-desc.*?addressing},
-   "Tried to put an inner-desc inside an addressing "
-);
+    # TEST
+    like ($err, qr{inner-desc.*?addressing},
+        "Tried to put an inner-desc inside an addressing "
+    );
+
+}
+
+{
+    my $grammar = XML::Grammar::Screenplay::FromProto->new({
+        parser_class => "XML::Grammar::Screenplay::FromProto::Parser::QnD",
+    });
+
+    eval {
+        my $got_xml = $grammar->convert(
+            {
+                source =>
+                {
+                    file => "t/screenplay/data/proto-text-invalid/non-terminated-desc.txt",
+                },
+            }
+        );
+    };
+
+    my $err = $@;
+
+    # TEST
+    like ($err, qr{Tag not closed at EOF},
+        "Screenplay with a description that did not terminate"
+    );
+
+}
 
 1;
+