From 880ff81eff7629dff04b98deb3ecf42e4658279f Mon Sep 17 00:00:00 2001 From: Deon George Date: Sun, 28 Nov 2021 14:02:50 +1100 Subject: [PATCH] Fix for when packets contain binary messages with SOH chars. Added testing for packet parsing --- app/Classes/FTN/Message.php | 68 +++++++++++++-------- tests/Feature/PacketTest.php | 51 ++++++++++++++++ tests/Feature/data/test_binary_content.pkt | Bin 0 -> 1207 bytes 3 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 tests/Feature/data/test_binary_content.pkt diff --git a/app/Classes/FTN/Message.php b/app/Classes/FTN/Message.php index 5832d0b..bcdae37 100644 --- a/app/Classes/FTN/Message.php +++ b/app/Classes/FTN/Message.php @@ -385,6 +385,7 @@ class Message extends FTNBase case 'seenaddress': case 'rogue_path': case 'rogue_seen': + case 'unknown': case 'via': case 'errors': @@ -679,24 +680,36 @@ class Message extends FTNBase $this->message = ''; $this->message_src = ''; - $srcpos = 0; + $msgpos = 0; + + foreach ($result as $kl) { + // $kl is our line starting with a \x01 kludge delimiter - foreach ($result as $v) { // Search for \r - if that is the end of the line, then its a kludge - $x = strpos($v,"\r"); + $retpos = strpos($kl,"\r"); + $msgpos += 1+strlen($kl); // SOH+text $t = ''; - $srcpos += 1+$x+1; // SOH+text+\r - // If there are more characters, then put the kludge back into the result, so that we process it. - if ($x != strlen($v)-1) { + // If there are is a return in this middle of this line, that means the text message starts after the return + // If our message has started, then we'll assume the binary is part of the message. + if (strlen($this->message) || ($retpos != strlen($kl)-1)) { // Anything after the origin line is also kludge data. - if ($y = strpos($v,"\r * Origin: ")) { - $this->message .= substr($v,$x+1,$y-$x-1); - $this->parseOrigin(substr($v,$y)); + if (($originpos = strpos($kl,"\r * Origin: "))) { + if (! $this->message) { + $this->message .= substr($kl,$retpos+1,$originpos-$retpos-1); + $this->parseOrigin(substr($kl,$originpos+1)); + $kl = substr($kl,0,$retpos); - // Capture the raw message, in case we send it on - // length = src, remove current 1+$x+1, add soh, $y + origin_start + origin_length + 0d - $this->message_src .= substr($message,0,$srcpos-(1+$x+1)+1+$y+12+strlen($this->origin)+1); + $this->message_src = substr($message, 0, $msgpos - strlen($kl) + 9); + + } else { + $this->message .= "\x01".substr($kl,0,$originpos); + $this->parseOrigin(substr($kl,$originpos+1)); + + // Capture the raw message, in case we send it on + $this->message_src = substr($message, 0, $msgpos - strlen($kl) - 1 + $originpos + 12 + strlen($this->origin) + 1); + $kl = ''; + } // If this is netmail, the FQFA will have been set by the INTL line, we can skip the rest of this $matches = []; @@ -719,16 +732,17 @@ class Message extends FTNBase } // The message is the rest? - } elseif (strlen($v) > $x+1) { - $this->message .= substr($v,$x+1); - $this->message_src .= substr($v,$x+1); + } elseif (strlen($kl) > $retpos+1) { + $this->message .= substr($kl,$retpos+1); + $kl = substr($kl,0,$retpos); } - $v = substr($v,0,$x+1); + if (! $kl) + continue; } foreach ($this->_kludge as $a => $b) { - if ($t = $this->kludge($b,$v)) { + if ($t = $this->kludge($b,$kl)) { $this->kludge->put($a,$t); break; } @@ -739,7 +753,7 @@ class Message extends FTNBase continue; // From point: "FMPT - if ($t = $this->kludge('FMPT ',$v)) + if ($t = $this->kludge('FMPT ',$kl)) $this->point['src'] = $t; /* @@ -749,7 +763,7 @@ class Message extends FTNBase * * "INTL "" " */ - elseif ($t = $this->kludge('INTL ',$v)) { + elseif ($t = $this->kludge('INTL ',$kl)) { $this->intl = $t; // INTL kludge is in Netmail, so we'll do some validation: @@ -766,32 +780,32 @@ class Message extends FTNBase } } - elseif ($t = $this->kludge('TZUTC: ',$v)) + elseif ($t = $this->kludge('TZUTC: ',$kl)) $this->tzutc = $t; - elseif ($t = $this->kludge('MSGID: ',$v)) + elseif ($t = $this->kludge('MSGID: ',$kl)) $this->msgid = $t; - elseif ($t = $this->kludge('PATH: ',$v)) + elseif ($t = $this->kludge('PATH: ',$kl)) $this->path->push($t); - elseif ($t = $this->kludge('RESCANNED ',$v)) + elseif ($t = $this->kludge('RESCANNED ',$kl)) $this->rescanned->push($t); - elseif ($t = $this->kludge('SEEN-BY: ',$v)) + elseif ($t = $this->kludge('SEEN-BY: ',$kl)) $this->seenby->push($t); // To Point: TOPT - elseif ($t = $this->kludge('TOPT ',$v)) + elseif ($t = $this->kludge('TOPT ',$kl)) $this->point['dst'] = $t; // Via @YYYYMMDD.HHMMSS[.Precise][.Time Zone] [Serial Number] - elseif ($t = $this->kludge('Via ',$v)) + elseif ($t = $this->kludge('Via ',$kl)) $this->via->push($t); // We got a kludge line we dont know about else - $this->unknown->push(chop($v,"\r")); + $this->unknown->push(chop($kl,"\r")); } // Work out our zone/point diff --git a/tests/Feature/PacketTest.php b/tests/Feature/PacketTest.php index d7eb6d7..632a60d 100644 --- a/tests/Feature/PacketTest.php +++ b/tests/Feature/PacketTest.php @@ -115,4 +115,55 @@ class PacketTest extends TestCase $this->assertTrue($messages); } + + public function test_packet_parse() + { + // This packet has an incorrect zone in the Origin + $f = new File(__DIR__.'/data/test_binary_content.pkt'); + $pkt = Packet::open($f,NULL,FALSE); + + $this->assertEquals(1,$pkt->count()); + + $messages = FALSE; + foreach ($pkt as $msg) { + $messages = TRUE; + + $this->assertNotTrue($msg->isNetmail()); + $this->assertSame('21:1/126 eec6e958',$msg->msgid); + $this->assertSame('5a525cc1c393292dc65160a852d4d615',md5($msg->message)); + $this->assertSame('a3193edcc68521d4ed07da6db2aeb0b6',md5($msg->message_src)); + $this->assertCount(3,$msg->rogue_path); + $this->assertCount(161,$msg->rogue_seen); + $this->assertContains('1/995 2/100 116 1202 3/100 105 107 108 109 110 111 112 113 117 119',$msg->seenby); + $this->assertContains('1/126 100 3/100',$msg->path); + $this->assertCount(10,$msg->seenby); + $this->assertCount(0,$msg->unknown); + } + + $this->assertTrue($messages); + + // This packet has an incorrect zone in the Origin + $f = new File(__DIR__.'/data/test_msgid_origin.pkt'); + $pkt = Packet::open($f,NULL,FALSE); + + $this->assertEquals(1,$pkt->count()); + + $messages = FALSE; + foreach ($pkt as $msg) { + $messages = TRUE; + + $this->assertNotTrue($msg->isNetmail()); + $this->assertSame('10:999/1 612aecda',$msg->msgid); + $this->assertSame('61078e680cda04c8b5eba0f712582e70',md5($msg->message)); + $this->assertSame('b9d65d4f7319ded282f3f1986276ae79',md5($msg->message_src)); + $this->assertCount(1,$msg->pathaddress); + $this->assertCount(2,$msg->rogue_seen); + $this->assertContains('1/1 999/1 999',$msg->seenby); + $this->assertContains('999/1',$msg->path); + $this->assertCount(1,$msg->seenby); + $this->assertCount(0,$msg->unknown); + } + + $this->assertTrue($messages); + } } diff --git a/tests/Feature/data/test_binary_content.pkt b/tests/Feature/data/test_binary_content.pkt new file mode 100644 index 0000000000000000000000000000000000000000..35c5cbb2bf27a266473b74142606fcf049e6287e GIT binary patch literal 1207 zcmaKs+iDY06ow~yAuSAe(+ltRjo1olX0N?x&w(cG#7Pg>gEa9>v6D2EV62D4qEyh= z@J)OnU%^}bCT+DNB4N?V{NMV!_xcw(^1jV~zcJ_C^5*#@p66ZjuJid>dysXzkN5WT z1#f}3UhU>wji=dj`5o?v-jeldo+qK&8%&jGrL?3vNKNQv>+sHd^Q~Wp0N4Yw6ZbhAm@xRo*{`l-47Nf%#ng4d} zzH7N{h~kf?d;~hU$57%p6~SXfJy=h8bRFP zXp7sUllLDQ&Mx`tuG)JyIv$;*DjVOKsEy(9rP?m~s@|+C2D4m@C&#=S7yaeI>sP55 zF>3Mhl1qNK)7h=JpK`l~4g#eEO$lWvONEr9A}Xd5r8S&}V{%%