Commit:    151949772442ed3b9a1b5202a000ae88de1bc468
Author:    Ben Ramsey <[email protected]>         Sat, 23 Jan 2016 00:37:56 
-0500
Parents:   7cbd35c71a8e5c5c76178e19c23af2176f373d80
Branches:  master

Link:       
http://git.php.net/?p=web/news.git;a=commitdiff;h=151949772442ed3b9a1b5202a000ae88de1bc468

Log:
Use the Nntp and fMailbox classes to display messages and attachments

Changed paths:
  M  article.php

diff --git a/article.php b/article.php
index 7e40ce7..1f6921c 100644
--- a/article.php
+++ b/article.php
@@ -2,6 +2,10 @@
 
 require 'common.php';
 
+/* Prevents the poor mail server from suffering if it receives a message with 
many references */
+/* (References: <xxx> or In-Reply-To: <xxx>) */
+define('REFERENCES_LIMIT', 20);
+
 if (isset($_GET['article'])) {
        $article = (int)$_GET['article'];
 } else {
@@ -14,273 +18,159 @@ if (isset($_GET['group'])) {
        $group = false;
 }
 
-$s = nntp_connect(NNTP_HOST);
-if (!$s) {
-       error("Failed to connect to news server");
-}
+try {
+       $nntpClient = new \Web\News\Nntp(NNTP_HOST);
+       $message = $nntpClient->readArticle($article, $group);
 
-if ($group) {
-       $res = nntp_cmd($s,"GROUP $group",211);
-       if (!$res) {
-               error("Failed to select group");
+       if ($message === null) {
+               error('No article found');
        }
-}
 
-$res = nntp_cmd($s, "ARTICLE $article",220);
-if (!$res) {
-       error("Failed to get article ". $article);
-}
+       $mail = fMailbox::parseMessage($message);
 
-/* Prevents the poor mail server from suffering if it receives a message with 
many references */
-/* (References: <xxx> or In-Reply-To: <xxx>) */
-define( 'REFERENCES_LIMIT', 20 );
+       $rawReferences = [];
+       if (!empty($mail['headers']['references'])) {
+               $rawReferences = $mail['headers']['references'];
+       } elseif (!empty($mail['headers']['in-reply-to'])) {
+               $rawReferences = $mail['headers']['in-reply-to'];
+       }
 
-$started = 0;
-$inheaders = 1; $headers = array();
-$masterheaders = array();
-$mimetype = $boundary = $charset = $encoding = "";
-$mimecount = 0; // number of mime parts
-$boundaries = array();
-$lk = '';
-$linebuf = '';
-$insig = false;
-while (!feof($s)) {
-       $line = fgets($s);
-       if ($line == ".\r\n") break;
-       if ($inheaders && ($line == "\n" || $line == "\r\n")) {
-               if (empty($masterheaders)) {
-                       /* $masterheaders should contain the first headers with 
From, Subject, */
-                       /* etc., not the ones from multiparts */
-                       $masterheaders = $headers;
+       $references = [];
+       foreach ($rawReferences as $ref) {
+               $matches = [];
+               if (preg_match_all('/\<(.*?)\>/', $ref, $matches)) {
+                       foreach ($matches[0] as $match) {
+                               $references[] = $match;
+                       }
                }
+       }
 
-               $inheaders = 0;
-               if (isset($headers['content-type'])) {
-                       if (preg_match('/charset=(["\']?)([\w-]+)\1/i', 
$headers['content-type'], $m)) {
-                               $charset = trim($m[2]);
-                       }
-               
-                       if(preg_match('/boundary=(["\']?)(.+)\1/is', 
$headers['content-type'], $m)) {
-                               $boundaries[] = trim($m[2]);
-                               $boundary = end($boundaries);
-                       }
+       $refsResolved = [];
 
-                       if (preg_match("/([^;]+)(;|\$)/", 
$headers['content-type'], $m)) {
-                               $mimetype = trim(strtolower($m[1]));
-                               ++$mimecount;
-                       }
-               }
-               if (!$started) {
-                       head("$group: ".format_title($headers['subject'], 
$charset));
-                       start_article($group, $masterheaders, $charset);
-                       $started = 1;
+       $refCount = 0;
+       foreach ($references as $messageId) {
+               if (!$messageId) {
+                       continue;
                }
-
-               if (!empty($headers['content-transfer-encoding'])) {
-                       $encoding = 
strtolower(trim($headers['content-transfer-encoding']));
+               if ($refCount >= REFERENCES_LIMIT) {
+                       break;
                }
-               if (strlen($mimetype)
-               && $mimetype != "text/plain"
-               && substr($mimetype,0,10) != "multipart/") {
-                       # Display a link to the attachment
-                       $name = '';
-                       if (!empty($headers['content-type'])
-                       && preg_match('/name=(["\']?)(.+)\1/s', 
$headers['content-type'], $m)) {
-                               $name = trim($m[2]);
-                       } else if (!empty($headers['content-disposition'])
-                       && preg_match('/filename=(["\']?)(.+)\1/s', 
$headers['content-disposition'], $m)) {
-                               $name = trim($m[2]);
-                       }
+               $refsResolved[] = $nntpClient->xpath($messageId);
+               $refCount++;
+       }
+} catch (Exception $e) {
+       error($e->getMessage());
+}
 
-                       if (!empty($headers['content-description'])) {
-                               $description = 
trim($headers['content-description']) . " ";
-                       } else {
-                               $description = '';
-                       }
+head("{$group}: " . format_title($mail['headers']['subject'], 'utf-8'));
+start_article($mail, $refsResolved);
 
-                       $description .= $name;
-                       $link_desc = "[$mimetype]";
-                       if (strlen($description)) {
-                               $link_desc .= " " . $description;
-                       }
+$lines = preg_split("@(?<=\r\n|\n)@", $mail['text']);
+$insig = 0;
 
-                       $dl_link = 
"/getpart.php?group=$group&amp;article=$article&amp;part=$mimecount";
-                       $link_desc = 
htmlspecialchars($link_desc,ENT_QUOTES,"UTF-8");
-                       
-                       /* Attachment filename and mimetype might contain 
malicious characters */
-                       printf('Attachment: <a href="%s">%s</a><br />'."\n",
-                               $dl_link,
-                               htmlspecialchars($link_desc)
-                       );
-               }
-
-               continue;
-       }
+foreach ($lines as $line) {
        # fix lines that started with a period and got escaped
        if (substr($line,0,2) == "..") {
                $line = substr($line,1);
        }
 
-       if ($inheaders) {
-               /* header fields can be split across lines: CRLF WSP where WSP 
*/
-               /* is a space (ASCII 32) or tab (ASCII 9) */
-               if ($lk && ($line[0] == ' ' || $line[0] == "\t")) {
-                       $headers[$lk] .= $line;
-               } else {
-                       @list($k,$v) = explode(": ", $line, 2);
-                       if ($k && $v) {
-                               $headers[strtolower($k)] = $v;
-                               $lk = strtolower($k);
-                       } // else not a header field
-               }
+       # this is some amazingly simplistic code to color quotes/signatures
+       # differently, and turn links into real links. it actually appears
+       # to work fairly well, but could easily be made more sophistimicated.
+       /* NOQUOTES? Why? It creates invalid HTML: http:"x */
+       $line = htmlentities($line,ENT_QUOTES,"utf-8");
+       $line = 
preg_replace("/((mailto|https?|ftp|nntp|news):.+?)(&gt;|\\s|\\)|\\.\\s|$)/","<a 
href=\"\\1\">\\1</a>\\3",$line);
+       if (!$insig && ($line == "-- \r\n" || $line == "--\r\n")) {
+               echo "<span class=\"signature\">";
+               $insig = 1;
        }
-       else {
-
-               if ($boundary
-               && substr($line,0,2) == '--'
-               && substr($line,2,strlen($boundary)) == $boundary) {
+       if (!$insig && substr($line,0,4) == "&gt;") {
+               echo "<span class=\"quote\">$line</span>";
+       } else {
+               echo $line;
+       }
+}
 
-                       $inheaders = 1;
+if ($insig) {
+       echo "</span>";
+       $insig = 0;
+}
 
-                       if (substr($line,2+strlen($boundary)) == '--') {
-                               # end of this container
-                               array_pop($boundaries);
-                               $boundary = end($boundaries);
-                       } else {
-                               /* Next section: start with no headers, default 
content type should be
-                               /* text/plain, but for now ignore that (see rfc 
2046  5.1.3) */
-                               $headers = array();
-                               $mimetype = "";
-                       }
+echo "<br><br>";
 
-                       continue;
-               }
+if (!empty($mail['attachment'])) {
+       foreach ($mail['attachment'] as $mimecount => $attachment) {
+               $mimetype = $attachment['mimetype'];
+               $name = $attachment['filename'];
 
-               if (strlen($mimetype) && $mimetype != "text/plain") {
+               if ($mimetype == 'text/plain') {
+                       echo htmlspecialchars($attachment['data']);
                        continue;
                }
 
-               switch($encoding) {
-                       case "quoted-printable":
-                       $line = quoted_printable_decode($line);
-                       break;
-                       case "base64":
-                       $line = base64_decode($line);
-                       break;
+               if (!empty($attachment['description'])) {
+                       $description = trim($attachment['description']) . " ";
+               } else {
+                       $description = '';
                }
 
-               // we can't convert it to UTF, because cvs commits don't have 
charset info
-               // so its preferable to leave it as-is, and let users choose 
the correct charset
-               // in their browser. this is specially important for php.doc.* 
groups
-               if ($charset && strpos(strtolower($charset), 'utf-8') === 
false) {
-                       $line = to_utf8($line, $charset);
+               $description .= $name;
+               $link_desc = "[$mimetype]";
+               if (strlen($description)) {
+                       $link_desc .= " " . $description;
                }
 
-               $line = $linebuf . $line;
+               $dl_link = 
"/getpart.php?group=$group&amp;article=$article&amp;part=$mimecount";
+               $link_desc = htmlspecialchars($link_desc,ENT_QUOTES,'UTF-8');
 
-               if (in_array(substr($line, -1), array("\n", "\r"))) {
-                  $linebuf = '';
-               } else {
-                  $linebuf = $line;
-                  continue;
-               }
-
-               # this is some amazingly simplistic code to color 
quotes/signatures
-               # differently, and turn links into real links. it actually 
appears
-               # to work fairly well, but could easily be made more 
sophistimicated.
-               /* NOQUOTES? Why? It creates invalid HTML: http:"x */
-               $line = htmlentities($line,ENT_QUOTES,"utf-8");
-               $line = 
preg_replace("/((mailto|https?|ftp|nntp|news):.+?)(&gt;|\\s|\\)|\\.\\s|$)/","<a 
href=\"\\1\">\\1</a>\\3",$line);
-               if (!$insig && $line == "-- \r\n") {
-                       echo "<span class=\"signature\">";
-                       $insig = 1;
-               }
-               if ($insig && $line == "\r\n") {
-                       echo "</span>";
-                       $insig = 0;
-               }
-               if (!$insig && substr($line,0,4) == "&gt;") {
-                       echo "<span class=\"quote\">$line</span>";
-               } else {
-                       echo $line;
-               }
+               /* Attachment filename and mimetype might contain malicious 
characters */
+               printf('Attachment: <a href="%s">%s</a><br />'."\n",
+                       $dl_link,
+                       htmlspecialchars($link_desc)
+               );
        }
 }
-if ($inheaders && !$started) {
-       head("$group: ". $headers['subject']);
-       start_article($group, $masterheaders, $charset);
-}
-if ($insig) {
-       echo "</span>";
-}
+
 echo "   </pre>\n";
 echo "  </blockquote>\n";
 
-function start_article($group, $headers, $charset) {
+function start_article($mail, $refsResolved) {
        echo "  <blockquote>\n";
        echo '   <table border="0" cellpadding="2" cellspacing="2" 
width="100%">' . "\n";
        # from
        echo '    <tr class="vcard">' . "\n";
        echo '     <td class="headerlabel">From:</td>' . "\n";
-       echo '     <td class="headervalue">' . format_author($headers['from'], 
$charset)."</td>\n";
+       echo '     <td class="headervalue">' . 
format_author($mail['headers']['from']['raw'], 'utf-8')."</td>\n";
        # date
        echo '     <td class="headerlabel">Date:</td>' . "\n";
-       echo '     <td class="headervalue">' . 
format_date($headers["date"])."</td>\n";
+       echo '     <td class="headervalue">' . 
format_date($mail['headers']['date'])."</td>\n";
        echo "    </tr>\n";
        # subject
        echo '    <tr>' . "\n";
        echo '     <td class="headerlabel">Subject:</td>' . "\n";
-       echo '     <td class="headervalue" 
colspan="3">'.format_subject($headers["subject"], $charset)."</td>\n";
+       echo '     <td class="headervalue" 
colspan="3">'.format_subject($mail['headers']['subject'], 'utf-8')."</td>\n";
        echo "    </tr>\n";
        echo "    <tr>\n";
        # references
-       if (!empty($headers['references']) || !empty($headers['in-reply-to'])) {
-               $ref = $headers["references"] ? $headers["references"] : 
$headers["in-reply-to"];
+       if (!empty($refsResolved)) {
                echo '     <td class="headerlabel">References:</td>' . "\n";
                echo '     <td class="headervalue">';
-               $r = explode(" ", $ref);
-               $c = 1;
-               $s = nntp_connect(NNTP_HOST)
-               or die("failed to connect to news server");
-               while (list($k,$v) = each($r)) {
-                       if (!$v) continue;
-                       $v = trim($v);
-                       if (!preg_match("/^<.+>\$/", $v)) {
-                               continue;
-                       }
-                       if (strlen($v) > 504) {
-                               // 512 chars including CRLF
-                               continue;
-                       }
-                       $res2 = nntp_cmd($s, "XPATH $v",223)
-                       or print("<!-- failed to get reference article id 
".htmlspecialchars($v, ENT_QUOTES, "UTF-8")." -->");
-                       list(,$v)  = split("/", trim($res2));
-                       if (empty($v)) {
-                               continue;
-                       }
-
-                       echo "<a href=\"/$group/". urlencode($v) 
."\">".($c++)."</a>&nbsp;";
-                       if ($c > REFERENCES_LIMIT) {
-                               printf('More than %d references', 
REFERENCES_LIMIT);
-                               break;
-                       }
+               foreach ($refsResolved as $k => $ref) {
+                       echo "<a href=\"/". urlencode($ref['group']) . '/' . 
urlencode($ref['articleId']) ."\">".($k + 1)."</a>&nbsp;";
                }
                echo "</td>\n";
        }
        # groups
-       if (!empty($headers["newsgroups"])) {
+       if (!empty($mail['headers']['newsgroups'])) {
                echo '     <td class="headerlabel">Groups:</td>' . "\n";
                echo '     <td class="headervalue">';
-               $r = explode(",", chop($headers["newsgroups"]));
+               $r = explode(",", rtrim($mail['headers']['newsgroups']));
                while (list($k,$v) = each($r)) {
                        echo "<a 
href=\"/".urlencode($v)."\">".htmlspecialchars($v)."</a>&nbsp;";
                }
                echo "</td>\n";
        }
        echo "    </tr>\n";
-       //while (list($k,$v) = each($headers)) {
-       //  echo "<!-- ", htmlspecialchars($k),": ",preg_replace("/-+/", "-", 
htmlspecialchars($v))," -->\n";
-       //}
        echo "   </table>\n";
        echo "  </blockquote>\n";
        echo "  <blockquote>\n";
-- 
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to