1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
Description: Fix parser error on auth failure
When I create a connection that has a bad password, I encounter the
following error (via warn) after receiving the sasl_error and
disconnect events:
.
parser error: Can't call method "NamespaceEnd" on an undefined value at
/usr/lib/perl5/vendor_perl/XML/Parser/Expat.pm line 614.
on [<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-
authorized/><text>The response provided by the client doesn't
match the one we calculated.</text></failure>]
.
What happens is that the AE::XMPP::Parser object gets rids of its expat
parser member in disconnect in response to the failure tag, but Expat
wants to keep parsing the string. I have attached a test file and a
patch to fix the bug.
Author: RHOELZ [...] cpan.org
Last-Update: 2011-05-23
Forwarded: yes
Origin: https://rt.cpan.org/Ticket/Attachment/789032/408830/patch
Bug: https://rt.cpan.org/Public/Bug/Display.html?id=58296
--- a/lib/AnyEvent/XMPP/Parser.pm
+++ b/lib/AnyEvent/XMPP/Parser.pm
@@ -119,8 +119,6 @@
sub cleanup {
my ($self) = @_;
- $self->{parser}->release;
-
for (qw(stanza_cb error_cb stream_cb parser)) {
delete $self->{$_};
}
@@ -247,4 +245,9 @@
=cut
+sub DESTROY {
+ my ($self) = @_;
+ $self->{parser}->release;
+}
+
1; # End of AnyEvent::XMPP
--- /dev/null
+++ b/t/z_parser_error.t
@@ -0,0 +1,49 @@
+#!perl
+
+use strict;
+no warnings;
+use Test::More;
+use AnyEvent::XMPP::Connection;
+
+unless($ENV{NET_XMPP2_TEST}) {
+ plan skip_all => 'Define NET_XMPP2_TEST to jid:password to test this';
+ exit 0;
+}
+plan tests => 3;
+my ( $jid ) = split /:/, $ENV{NET_XMPP2_TEST};
+
+my $conn = AnyEvent::XMPP::Connection->new(
+ jid => $jid,
+ password => '',
+);
+
+my $seen_warn = 0;
+my $seen_stream_ready = 0;
+my $seen_sasl_error = 0;
+
+$SIG{__WARN__} = sub {
+ $seen_warn = 1;
+};
+
+my $cond = AnyEvent->condvar;
+
+$conn->reg_cb(
+ stream_ready => sub {
+ $seen_stream_ready = 1;
+ $conn->disconnect;
+ },
+ sasl_error => sub {
+ $seen_sasl_error = 1;
+ },
+ disconnect => sub {
+ $cond->broadcast;
+ },
+);
+
+$conn->connect;
+
+$cond->wait;
+
+ok(! $seen_stream_ready, 'auth should fail');
+ok(! $seen_warn, 'no warnings should be emitted');
+ok($seen_sasl_error, 'I should see a SASL error');
|