Smartys wrote:
elbekko wrote:
LVZ wrote:

Can you name even one modern graphical web browser that will not properly display a GIF file even if it has the extension PNG?  If you can, I would consider that to be a very poorly designed browser.

That wouldn't be bad design, that would be following standards. Which browsers don't seem to want to do (but should do).

Indeed. When you have browsers guessing what content should be in a file, you have issues like this

While these exploits are real, I don't think that your premise is correct.  How are they connected in any way?

The links show what can happen when the extension is CORRECT.  How is this content guessing?

How would NOT guessing the intent of content improve this situation or in any way fix this particular vulnerability?

Let's talk about the real world, not purist theory.  I again ask, do you know ANY modern graphical web browser that cannot correctly render a GIF file with a PNG extension?

::

Jérémie wrote:

There's a life beyond MSIE you know.

Since I rarely use MSIE, that is rather irrelevant, isn't it?  Can you name even one modern graphical web browser that will not properly display a GIF file even if it has the extension PNG?  If you can, I would consider that to be a very poorly designed browser.

::

Jérémie wrote:

File extension and ... mismatch aren't a good idea.

Ah, the purist.  If it works fine with all major browsers, who cares?  No code changes to PunBB necessary.

If you want real PNG instead of GIF, they are here: http://lasvalley.com/702/img/smilies/convert/

I used a simple Linux gif2png.sh for conversion.  I'm sure that there are much better conversion tools.

These real PNGs are about 80% bigger than GIFs.  Maybe someone who cares can make them smaller.

::

Solution to viewtopic.php mod:

http://punbb.org/forums/viewtopic.php?id=16911#p99810

::

Nothing to explain.  These emoticons were collected from some of the hundreds of "smilie" sites on the internet. All are to some degree or another inspired by similar images.

Emoticons in this collection range from 94 to 304 bytes, with most under 200 bytes.

::

Jérémie wrote:

File extension and image size mismatch aren't a good idea.

And by the way, vB resources aren't free, or libre.

None of the 15x15 emoticons came from vB resources or any vB site.  As stated above, vB's emoticons are 16x16 and larger.  There are hundreds, maybe thousands of icon/emoticon developers on the internet.  Most allow free use of their creations. 

::

elbekko wrote:

Seems I was right. Resizing them isn't that hard now is it hmm

If you looked at my post, you will note that I collected them.  Resizing to 15x15 was not necessary.  BTW, resizing very small images like icons would typically yield less than desirable results.

Smartys wrote:

you have a couple there (the ones from vB) that are 16x16

The only 16x16 image left in the set is http://lasvalley.com/702/img/smilies/yikes16x16.gif      [ UPDATE: and now I found a better 15x15 one.  See #2 below. ]

Despite the size mismatch,  it seems to work with PunBB and I like it better than other alternatives.

For those who want only 15x15 emoticons, I might suggest these alternatives:

1. http://lasvalley.com/702/img/smilies/yikes.gif
2. http://lasvalley.com/702/img/smilies/more/yikes-2.gif
3. http://lasvalley.com/702/img/smilies/more/yikes-3.gif
4. http://lasvalley.com/702/img/smilies/more/yikes-4.gif
5. http://lasvalley.com/702/img/smilies/more/yikes-ani.gif

::

vB almost always uses 16x16 or larger.

::

I did not really like the original 15x15 PunBB emoticon set.  I have collected my own set.
Most images are really GIFs and not PNGs but web browsers don't care when the filename/extension matches.

* If you download, make sure that you save to filename.png and not filename.png.gif

:?) and =?) produces http://lasvalley.com/702/img/smilies/smile.png img/smilies/smile.png
:?| and =?| produces http://lasvalley.com/702/img/smilies/neutral.png img/smilies/neutral.png
:?( and =?( produces http://lasvalley.com/702/img/smilies/sad.png img/smilies/sad.png
:?D and =?D produces http://lasvalley.com/702/img/smilies/big_smile.png img/smilies/big_smile.png
:?o and :?O produces http://lasvalley.com/702/img/smilies/yikes.png img/smilies/yikes.png
;?) produces http://lasvalley.com/702/img/smilies/wink.png img/smilies/wink.png
:?/ produces http://lasvalley.com/702/img/smilies/hmm.png img/smilies/hmm.png
:?P produces http://lasvalley.com/702/img/smilies/tongue.png img/smilies/tongue.png
:?lol: produces http://lasvalley.com/702/img/smilies/lol.png img/smilies/lol.png
:?mad: produces http://lasvalley.com/702/img/smilies/mad.png img/smilies/mad.png
:?rolleyes: produces http://lasvalley.com/702/img/smilies/roll.png img/smilies/roll.png
:?cool: produces http://lasvalley.com/702/img/smilies/cool.png img/smilies/cool.png

http://lasvalley.com/702 forums

::

This was my solution.  Not a complete solution but it gets rid of over 90% of my spam problems.

http://punbb.org/forums/viewtopic.php?i … p=2#p96898

::

CSS display problems solved.  Forgot to add special polls CSS to the bottom of every Style.css file.

p.poll_info {
text-align: center;
clear: left;
margin: 7px;
}
div.poll_question {
float: left;
clear: both;
text-align: right;
width: 50%;
margin: 0.3em;
height: 1.2em;
}
div.poll_result,div.poll_result_yesno {
float: left;
text-align: left;
width: 45%;
margin: 0.3em;
padding: 0;
height: 1.2em;
line-height: 1.2em;
}
    div.poll_result_yesno {
    width: 22%;
    margin-right: 0.1em;
    }
img.poll_bar {
border-right: 2px solid #0066B9; /* teinte plus fonc? que la couleur principale du forum */
background-color: #006FC9; /* Couleur principale du forum */
height: 1.2em;
margin: 0;
}

Thanks elbekko.

I was able to grab/edit parts of your code and insert into my "clean" 1.2.15 viewtopic.php file:

SOLUTION: clean 1.2.15 viewtopic.php with Easy Poll + 2.0 code added

Go to "Test Posting Area" forum http://lasvalley.com/702/ user:demo password:demo

<?php // clean 1.2.15 viewtopic.php with Easy Poll + 2.0 (English) added.
/***********************************************************************

  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)

  This file is part of PunBB.

  PunBB is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published
  by the Free Software Foundation; either version 2 of the License,
  or (at your option) any later version.

  PunBB is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  MA  02111-1307  USA

************************************************************************/


define('PUN_ROOT', './');
require PUN_ROOT.'include/common.php';


if ($pun_user['g_read_board'] == '0')
    message($lang_common['No view']);


$action = isset($_GET['action']) ? $_GET['action'] : null;
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$pid = isset($_GET['pid']) ? intval($_GET['pid']) : 0;
if ($id < 1 && $pid < 1)
    message($lang_common['Bad request']);

// Load the viewtopic.php language file
require PUN_ROOT.'lang/'.$pun_user['language'].'/topic.php';

// Load poll language file
if(file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/polls.php'))
    require PUN_ROOT.'lang/'.$pun_user['language'].'/polls.php';
else
    require PUN_ROOT.'lang/English/polls.php';

// If a post ID is specified we determine topic ID and page number so we can redirect to the correct message
if ($pid)
{
    $result = $db->query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$pid) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    if (!$db->num_rows($result))
        message($lang_common['Bad request']);

    $id = $db->result($result);

    // Determine on what page the post is located (depending on $pun_user['disp_posts'])
    $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$id.' ORDER BY posted') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    $num_posts = $db->num_rows($result);

    for ($i = 0; $i < $num_posts; ++$i)
    {
        $cur_id = $db->result($result, $i);
        if ($cur_id == $pid)
            break;
    }
    ++$i;    // we started at 0

    $_GET['p'] = ceil($i / $pun_user['disp_posts']);
}

// If action=new, we redirect to the first new post (if any)
else if ($action == 'new' && !$pun_user['is_guest'])
{
    $result = $db->query('SELECT MIN(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id.' AND posted>'.$pun_user['last_visit']) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    $first_new_post_id = $db->result($result);

    if ($first_new_post_id)
        header('Location: viewtopic.php?pid='.$first_new_post_id.'#p'.$first_new_post_id);
    else    // If there is no new post, we go to the last post
        header('Location: viewtopic.php?id='.$id.'&action=last');

    exit;
}

// If action=last, we redirect to the last post
else if ($action == 'last')
{
    $result = $db->query('SELECT MAX(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    $last_post_id = $db->result($result);

    if ($last_post_id)
    {
        header('Location: viewtopic.php?pid='.$last_post_id.'#p'.$last_post_id);
        exit;
    }
}

// Fetch some info about the topic
if (!$pun_user['is_guest'])
    $result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, t.question, t.yes, t.no, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, s.user_id AS is_subscribed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
else
    $result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, t.question, t.yes, t.no, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());

if (!$db->num_rows($result))
    message($lang_common['Bad request']);

$cur_topic = $db->fetch_assoc($result);

// Sort out who the moderators are and if we are currently a moderator (or an admin)
$mods_array = ($cur_topic['moderators'] != '') ? unserialize($cur_topic['moderators']) : array();
$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;

// Can we or can we not post replies?
if ($cur_topic['closed'] == '0')
{
    if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1' || $is_admmod)
        $post_link = '<a href="post.php?tid='.$id.'">'.$lang_topic['Post reply'].'</a>';
    else
        $post_link = ' ';
}
else
{
    $post_link = $lang_topic['Topic closed'];

    if ($is_admmod)
        $post_link .= ' / <a href="post.php?tid='.$id.'">'.$lang_topic['Post reply'].'</a>';
}


// Determine the post offset (based on $_GET['p'])
$num_pages = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);

$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
$start_from = $pun_user['disp_posts'] * ($p - 1);

// Generate paging links
$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'viewtopic.php?id='.$id);


if ($pun_config['o_censoring'] == '1')
    $cur_topic['subject'] = censor_words($cur_topic['subject']);


$quickpost = false;
if ($pun_config['o_quickpost'] == '1' &&
    !$pun_user['is_guest'] &&
    ($cur_topic['post_replies'] == '1' || ($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1')) &&
    ($cur_topic['closed'] == '0' || $is_admmod))
{
    $required_fields = array('req_message' => $lang_common['Message']);
    $quickpost = true;
}

if (!$pun_user['is_guest'] && $pun_config['o_subscriptions'] == '1')
{
    if ($cur_topic['is_subscribed'])
        // I apologize for the variable naming here. It's a mix of subscription and action I guess :-)
        $subscraction = '<p class="subscribelink clearb">'.$lang_topic['Is subscribed'].' - <a href="misc.php?unsubscribe='.$id.'">'.$lang_topic['Unsubscribe'].'</a></p>'."\n";
    else
        $subscraction = '<p class="subscribelink clearb"><a href="misc.php?subscribe='.$id.'">'.$lang_topic['Subscribe'].'</a></p>'."\n";
}
else
    $subscraction = '<div class="clearer"></div>'."\n";

$page_title = pun_htmlspecialchars($pun_config['o_board_title'].' / '.$cur_topic['subject']);
define('PUN_ALLOW_INDEX', 1);
require PUN_ROOT.'header.php';

?>
<div class="linkst">
    <div class="inbox">
        <p class="pagelink conl"><?php echo $paging_links ?></p>
        <p class="postlink conr"><?php echo $post_link ?></p>
        <ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li> » <a href="viewforum.php?id=<?php echo $cur_topic['forum_id'] ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li> » <?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
        <div class="clearer"></div>
    </div>
</div>

<?php


require PUN_ROOT.'include/parser.php';

$bg_switch = true;    // Used for switching background color in posts
$post_count = 0;    // Keep track of post numbers

// ==================================================================== Mod poll begin
if ($cur_topic['question'])
// if ( TRUE )
{
//    require PUN_ROOT . 'lang/' . $pun_user['language'] . '/polls.php'; 
    // get the poll data
    $result = $db->query('SELECT ptype,options,voters,votes FROM ' . $db->prefix . 'polls WHERE pollid=' . $id . '') or error('Unable to fetch poll info', __FILE__, __LINE__, $db->error());

    if (!$db->num_rows($result))
        message($lang_common['Bad request']);

    $cur_poll = $db->fetch_assoc($result);

    $options = unserialize($cur_poll['options']);
    if (!empty($cur_poll['voters']))
        $voters = unserialize($cur_poll['voters']);
    else
        $voters = array();

    $ptype = $cur_poll['ptype']; 
    // yay memory!
    // $cur_poll = null;
    $firstcheck = false;
    ?>
<div class="blockform">
    <h2><span><?php echo $lang_polls['Poll'] ?></span></h2>
    <div class="box">
        <?php
    if ((!$pun_user['is_guest']) && (!in_array($pun_user['id'], $voters)) && ($cur_topic['closed'] == '0') && (($cur_topic['post_replies'] == '1' || ($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1')) || $is_admmod)) 
    {
        $showsubmit = true;
        ?>
        <form id="post" method="post" action="vote.php">
            <div class="inform">
                <div class="rbox">
                <fieldset>
                    <legend><?php echo pun_htmlspecialchars($cur_topic['question']) ?></legend>
                    <div class="infldset txtarea">
                        <input type="hidden" name="poll_id" value="<?php echo $id; ?>" />
                        <input type="hidden" name="form_sent" value="1" />
                        <input type="hidden" name="form_user" value="<?php echo (!$pun_user['is_guest']) ? pun_htmlspecialchars($pun_user['username']) : 'Guest'; ?>" />
    
                        <?php
                        if ($ptype == 1) 
                        {
                            while (list($key, $value) = each($options)) 
                            {
                            ?>
                                <label><input name="vote" <?php if (!$firstcheck) { echo 'checked="checked"'; $firstcheck = true; }; ?> type="radio" value="<?php echo $key ?>" /> <span><?php echo pun_htmlspecialchars($value); ?></span></label>
                            <?php
                            } 
                        } 
                        elseif ($ptype == 2) 
                        {
                            while (list($key, $value) = each($options)) 
                            {         
                            ?>
                                <label><input name="options[<?php echo $key ?>]" type="checkbox" value="1" /> <span><?php echo pun_htmlspecialchars($value); ?></span></label>
                            <?php
                            } 
                        } 
                        elseif ($ptype == 3) 
                        {
                            
                            while (list($key, $value) = each($options)) 
                            {
                                echo pun_htmlspecialchars($value); ?>
                                <label><input name="options[<?php echo $key ?>]" checked="checked" type="radio" value="yes" /> <?php echo $cur_topic['yes']; ?></label>
                                <label><input name="options[<?php echo $key ?>]" type="radio" value="no" /> <?php echo $cur_topic['no']; ?></label>
                                <br />
                            <?php
                            } 
                        } 
                        else
                        {
                            message($lang_common['Bad request']);
                        }
            ?></div></fieldset><?php
    } 
    else 
    {
        $showsubmit = false;
        ?>
        <div class="inform">
        <div class="rbox">
            
            <p class="poll_info"><strong><?php echo pun_htmlspecialchars($cur_topic['question']) ?></strong></p>            
            <?php
            if (!empty($cur_poll['votes']))
                    $votes = unserialize($cur_poll['votes']);
            else
                  $votes = array();
        
            if ($ptype == 1 || $ptype == 2) 
            {
                $total = 0;
                $percent = 0;
                $percent_int = 0;
                while (list($key, $val) = each($options)) 
                {
                    if (isset($votes[$key]))
                        $total += $votes[$key];
                }
                reset($options);
            }
            
              while (list($key, $value) = each($options)) {    

                if ($ptype == 1 || $ptype == 2)
                { 
                    if (isset($votes[$key]))
                    {
                        $percent =  $votes[$key] * 100 / $total;
                        $percent_int = floor($percent);
                    }
                    ?>
                        <div class="poll_question"><?php echo pun_htmlspecialchars($value); ?></div>
                        <div class="poll_result">
                            <img src="img/transparent.gif" class="poll_bar" style="width:<?php if (isset($votes[$key])) echo $percent_int/2; else echo '0'; ?>%;" alt="" />
                            <span><?php if (isset($votes[$key])) echo $percent_int . '% - ' . $votes[$key]; else echo '0% - 0'; ?></span>
                        </div>
                <?php
                }
                else if ($ptype == 3) 
                { 
                    $total = 0;
                    $yes_percent = 0;
                    $no_percent = 0;
                    $vote_yes = 0;
                    $vote_no = 0;
                    if (isset($votes[$key]['yes']))
                    {
                        $vote_yes = $votes[$key]['yes'];
                    }

                    if (isset($votes[$key]['no'])) {
                        $vote_no += $votes[$key]['no'];
                    }

                    $total = $vote_yes + $vote_no;
                    if (isset($votes[$key]))
                    {
                        $yes_percent =   floor($vote_yes * 100 / $total);
                        $no_percent = floor($vote_no * 100 / $total);
                    }
                    ?>
                        <div class="poll_question"><?php echo pun_htmlspecialchars($value); ?></div>
                        
                        <div class="poll_result_yesno">
                            <strong><?php echo $cur_topic['yes']; ?></strong>
                                <img src="img/transparent.gif" class="poll_bar" style="width:<?php if (isset($votes[$key]['yes'])) { echo $yes_percent/2; } else { echo '0';  } ?>%;" alt="" />
                                <span><?php if (isset($votes[$key]['yes'])) { echo $yes_percent . "% - " . $votes[$key]['yes']; } else { echo "0% - " . 0; } ?></span>
                        </div>
                        <div class="poll_result_yesno">                        
                            <strong><?php echo $cur_topic['no']; ?></strong>
                                <img src="img/transparent.gif" class="poll_bar" style="width:<?php if (isset($votes[$key]['no'])) { echo $no_percent/2; } else { echo '0';  } ?>%;" alt="" />
                                <span><?php if (isset($votes[$key]['no'])) { echo $no_percent . "% - " . $votes[$key]['no']; } else { echo "0% - " . 0; } ?></span>
                        </div>
                    <?php 
                }
                else
                message($lang_common['Bad request']);
            }     
            ?>
                <p class="poll_info">Total : <?php echo $total; ?></p>
            <?php
        } 
        ?>
            </div>
                
            </div>

            <?php if ($showsubmit == true) 
            { 
                echo '<p><input type="submit" name="submit" tabindex="2" value="' . $lang_common['Submit'] . '" accesskey="s" /> <input type="submit" name="null" tabindex="2" value="' . $lang_polls['Null vote']. '" accesskey="n" /></p>
                </form>';
            } 
            ?>
    </div>
</div>
<?php
}
// ===================================================== Mod poll end


// Retrieve the posts (and their respective poster/online status)
$result = $db->query('SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id LEFT JOIN '.$db->prefix.'online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id='.$id.' ORDER BY p.id LIMIT '.$start_from.','.$pun_user['disp_posts'], true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
while ($cur_post = $db->fetch_assoc($result))
{
    $post_count++;
    $user_avatar = '';
    $user_info = array();
    $user_contacts = array();
    $post_actions = array();
    $is_online = '';
    $signature = '';

    // If the poster is a registered user.
    if ($cur_post['poster_id'] > 1)
    {
        $username = '<a href="profile.php?id='.$cur_post['poster_id'].'">'.pun_htmlspecialchars($cur_post['username']).'</a>';
        $user_title = get_title($cur_post);

        if ($pun_config['o_censoring'] == '1')
            $user_title = censor_words($user_title);

        // Format the online indicator
        $is_online = ($cur_post['is_online'] == $cur_post['poster_id']) ? '<strong>'.$lang_topic['Online'].'</strong>' : $lang_topic['Offline'];

        if ($pun_config['o_avatars'] == '1' && $cur_post['use_avatar'] == '1' && $pun_user['show_avatars'] != '0')
        {
            if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.gif'))
                $user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.gif" '.$img_size[3].' alt="" />';
            else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.jpg'))
                $user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.jpg" '.$img_size[3].' alt="" />';
            else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.png'))
                $user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.png" '.$img_size[3].' alt="" />';
        }
        else
            $user_avatar = '';

        // We only show location, register date, post count and the contact links if "Show user info" is enabled
        if ($pun_config['o_show_user_info'] == '1')
        {
            if ($cur_post['location'] != '')
            {
                if ($pun_config['o_censoring'] == '1')
                    $cur_post['location'] = censor_words($cur_post['location']);

                $user_info[] = '<dd>'.$lang_topic['From'].': '.pun_htmlspecialchars($cur_post['location']);
            }

            $user_info[] = '<dd>'.$lang_common['Registered'].': '.date($pun_config['o_date_format'], $cur_post['registered']);

            if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST)
                $user_info[] = '<dd>'.$lang_common['Posts'].': '.$cur_post['num_posts'];

            // Now let's deal with the contact links (E-mail and URL)
            if (($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) || $pun_user['g_id'] < PUN_GUEST)
                $user_contacts[] = '<a href="mailto:'.$cur_post['email'].'">'.$lang_common['E-mail'].'</a>';
            else if ($cur_post['email_setting'] == '1' && !$pun_user['is_guest'])
                $user_contacts[] = '<a href="misc.php?email='.$cur_post['poster_id'].'">'.$lang_common['E-mail'].'</a>';

            if ($cur_post['url'] != '')
                $user_contacts[] = '<a href="'.pun_htmlspecialchars($cur_post['url']).'">'.$lang_topic['Website'].'</a>';
        }

        if ($pun_user['g_id'] < PUN_GUEST)
        {
            $user_info[] = '<dd>IP: <a href="moderate.php?get_host='.$cur_post['id'].'">'.$cur_post['poster_ip'].'</a>';

            if ($cur_post['admin_note'] != '')
                $user_info[] = '<dd>'.$lang_topic['Note'].': <strong>'.pun_htmlspecialchars($cur_post['admin_note']).'</strong>';
        }
    }
    // If the poster is a guest (or a user that has been deleted)
    else
    {
        $username = pun_htmlspecialchars($cur_post['username']);
        $user_title = get_title($cur_post);

        if ($pun_user['g_id'] < PUN_GUEST)
            $user_info[] = '<dd>IP: <a href="moderate.php?get_host='.$cur_post['id'].'">'.$cur_post['poster_ip'].'</a>';

        if ($pun_config['o_show_user_info'] == '1' && $cur_post['poster_email'] != '' && !$pun_user['is_guest'])
            $user_contacts[] = '<a href="mailto:'.$cur_post['poster_email'].'">'.$lang_common['E-mail'].'</a>';
    }

    // Generation post action array (quote, edit, delete etc.)
    if (!$is_admmod)
    {
        if (!$pun_user['is_guest'])
            $post_actions[] = '<li class="postreport"><a href="misc.php?report='.$cur_post['id'].'">'.$lang_topic['Report'].'</a>';

        if ($cur_topic['closed'] == '0')
        {
            if ($cur_post['poster_id'] == $pun_user['id'])
            {
                if ((($start_from + $post_count) == 1 && $pun_user['g_delete_topics'] == '1') || (($start_from + $post_count) > 1 && $pun_user['g_delete_posts'] == '1'))
                    $post_actions[] = '<li class="postdelete"><a href="delete.php?id='.$cur_post['id'].'">'.$lang_topic['Delete'].'</a>';
                if ($pun_user['g_edit_posts'] == '1')
                    $post_actions[] = '<li class="postedit"><a href="edit.php?id='.$cur_post['id'].'">'.$lang_topic['Edit'].'</a>';
            }

            if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1')
                $post_actions[] = '<li class="postquote"><a href="post.php?tid='.$id.'&qid='.$cur_post['id'].'">'.$lang_topic['Quote'].'</a>';
        }
    }
    else
        $post_actions[] = '<li class="postreport"><a href="misc.php?report='.$cur_post['id'].'">'.$lang_topic['Report'].'</a>'.$lang_topic['Link separator'].'</li><li class="postdelete"><a href="delete.php?id='.$cur_post['id'].'">'.$lang_topic['Delete'].'</a>'.$lang_topic['Link separator'].'</li><li class="postedit"><a href="edit.php?id='.$cur_post['id'].'">'.$lang_topic['Edit'].'</a>'.$lang_topic['Link separator'].'</li><li class="postquote"><a href="post.php?tid='.$id.'&qid='.$cur_post['id'].'">'.$lang_topic['Quote'].'</a>';


    // Switch the background color for every message.
    $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
    $vtbg = ($bg_switch) ? ' roweven' : ' rowodd';


    // Perform the main parsing of the message (BBCode, smilies, censor words etc)
    $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);

    // Do signature parsing/caching
    if ($cur_post['signature'] != '' && $pun_user['show_sig'] != '0')
    {
        if (isset($signature_cache[$cur_post['poster_id']]))
            $signature = $signature_cache[$cur_post['poster_id']];
        else
        {
            $signature = parse_signature($cur_post['signature']);
            $signature_cache[$cur_post['poster_id']] = $signature;
        }
    }

?>
<div id="p<?php echo $cur_post['id'] ?>" class="blockpost<?php echo $vtbg ?><?php if (($post_count + $start_from) == 1) echo ' firstpost'; ?>">
    <h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?> </span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
    <div class="box">
        <div class="inbox">
            <div class="postleft">
                <dl>
                    <dt><strong><?php echo $username ?></strong></dt>
                    <dd class="usertitle"><strong><?php echo $user_title ?></strong></dd>
                    <dd class="postavatar"><?php echo $user_avatar ?></dd>
<?php if (count($user_info)) echo "\t\t\t\t\t".implode('</dd>'."\n\t\t\t\t\t", $user_info).'</dd>'."\n"; ?>
<?php if (count($user_contacts)) echo "\t\t\t\t\t".'<dd class="usercontacts">'.implode('  ', $user_contacts).'</dd>'."\n"; ?>
                </dl>
            </div>
            <div class="postright">
                <h3><?php if (($post_count + $start_from) > 1) echo ' Re: '; ?><?php echo pun_htmlspecialchars($cur_topic['subject']) ?></h3>
                <div class="postmsg">
                    <?php echo $cur_post['message']."\n" ?>
<?php if ($cur_post['edited'] != '') echo "\t\t\t\t\t".'<p class="postedit"><em>'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')</em></p>'."\n"; ?>
                </div>
<?php if ($signature != '') echo "\t\t\t\t".'<div class="postsignature"><hr />'.$signature.'</div>'."\n"; ?>
            </div>
            <div class="clearer"></div>
            <div class="postfootleft"><?php if ($cur_post['poster_id'] > 1) echo '<p>'.$is_online.'</p>'; ?></div>
            <div class="postfootright"><?php echo (count($post_actions)) ? '<ul>'.implode($lang_topic['Link separator'].'</li>', $post_actions).'</li></ul></div>'."\n" : '<div> </div></div>'."\n" ?>
        </div>
    </div>
</div>

<?php

}

?>
<div class="postlinksb">
    <div class="inbox">
        <p class="postlink conr"><?php echo $post_link ?></p>
        <p class="pagelink conl"><?php echo $paging_links ?></p>
        <ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li> » <a href="viewforum.php?id=<?php echo $cur_topic['forum_id'] ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li> » <?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
        <?php echo $subscraction ?>
    </div>
</div>

<?php

// Display quick post if enabled
if ($quickpost)
{

?>
<div class="blockform">
    <h2><span><?php echo $lang_topic['Quick post'] ?></span></h2>
    <div class="box">
        <form method="post" action="post.php?tid=<?php echo $id ?>" onsubmit="this.submit.disabled=true;if(process_form(this)){return true;}else{this.submit.disabled=false;return false;}">
            <div class="inform">
                <fieldset>
                    <legend><?php echo $lang_common['Write message legend'] ?></legend>
                    <div class="infldset txtarea">
                        <input type="hidden" name="form_sent" value="1" />
                        <input type="hidden" name="form_user" value="<?php echo (!$pun_user['is_guest']) ? pun_htmlspecialchars($pun_user['username']) : 'Guest'; ?>" />
                        <label><textarea name="req_message" rows="7" cols="75" tabindex="1"></textarea></label>
                        <ul class="bblinks">
                            <li><a href="help.php#bbcode" onclick="window.open(this.href); return false;"><?php echo $lang_common['BBCode'] ?></a>: <?php echo ($pun_config['p_message_bbcode'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
                            <li><a href="help.php#img" onclick="window.open(this.href); return false;"><?php echo $lang_common['img tag'] ?></a>: <?php echo ($pun_config['p_message_img_tag'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
                            <li><a href="help.php#smilies" onclick="window.open(this.href); return false;"><?php echo $lang_common['Smilies'] ?></a>: <?php echo ($pun_config['o_smilies'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
                        </ul>
                    </div>
                </fieldset>
            </div>
            <p><input type="submit" name="submit" tabindex="2" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
        </form>
    </div>
</div>
<?php

}

// Increment "num_views" for topic
$low_prio = ($db_type == 'mysql') ? 'LOW_PRIORITY ' : '';
$db->query('UPDATE '.$low_prio.$db->prefix.'topics SET num_views=num_views+1 WHERE id='.$id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());

$forum_id = $cur_topic['forum_id'];
$footer_style = 'viewtopic';
require PUN_ROOT.'footer.php';

::

Although there are two poll mods out there, from what I can tell, neither works (in English) with the latest PunBB 1.2.15 version.  Is that correct?  If not, is there a working 1.2.15 example site where polling is working?

I have had no success with a modded Easy Poll + 2.0 viewtopic.php file although the other EP+2 files seem to work.

::

Does anyone have a viewable link (viewtopic.php.txt) to a working English 1.2.15 viewtopic.php file with a working Easy Poll + 2.0 function?

All other modded Easy Poll + files appear to work for me: polls can be created and the data appears okay in the mySQL database.  However, if I try to use a modded Easy Poll + 2.0 viewtopic.php file ( example: http://elbekko.pastebin.ca/raw/359578 ), I simply get "Error: Unable to fetch topic info."

This would be a great polling MOD if it actually worked in English.

::

P.S.  Even a link to a working 1.2.15 French viewable Easy Poll + 2.0 viewtopic.php.txt file might be useful.
I could make the French to English updates later.  I consider a message board poll feature to be an essential one.

P.P.S. Is there ANY poll mod that works (in English) with 1.2.15 ?

15

(2 replies, posted in General discussion)

pcfy2 wrote:

I am having trouble accessing the eeenix forum.

I keep getting a forbidden sever error message.

Are there problems with the server for this forum?

http://www.eeenix.org/forum/index.php

The Eeenix guy took his Linux project for the Asus Eee private.  I think there is an effort to carry on anyway by some other ex-Eeenix project advocates.

http://www.eeeuser.com/forums/viewtopic … 1698#p1698

::

16

(30 replies, posted in PunBB 1.2 discussion)

Smartys wrote:

You might want to look at this
http://us2.php.net/manual/en/function.gethostbyaddr.php

I did that before I wrote the code.  However, I did notice these comments on php.net

gethostbyaddr() tends to lag on various systems for whatever reason. Here are two functions that should prove their worth speedwise.

// For Linux...

function gethost ($ip) {
$host = `host $ip`;
return (($host ? end ( explode (' ', $host)) : $ip));
}

17

(30 replies, posted in PunBB 1.2 discussion)

Okay, I did a bit more anti-spam testing to not only just allow certain email address TLDs but to also just allow the same (or different) reverse-IP posting TLDs.  The example below is for USA email addresses and IPs.  It does not, of course, eliminate spam postings, but it can significantly reduce the problem.

For limited testing, you can try my unannounced http://vegasmusictalk.com/lvss/forum/

For those who just want to deny instead of allow a set of TLDs:

instead  of  allow: $TLD_em != 'com' && $TLD_em != 'net' && $TLD_em != 'org' && etc.
use method deny: $TLD_em == '.ru' || $TLD_em == '.ro' || $TLD_em == 'biz' || etc.

Changes made in include/email.php :

//
// TLD check - reduce allowable top level domains for email addresses and reverse-ip registrations
//
function TLD_check($TLD_em,$ip)  // restricted to .com .org .net .edu .gov .ca and unresolvable IP
{
   if( $TLD_em != 'com' && $TLD_em != 'net' && $TLD_em != 'org' &&
       $TLD_em != 'edu' && $TLD_em != 'gov' && $TLD_em != '.ca' )        return true; 
// not allowed

   $TLD_ip=end(explode(' ',`host $ip`));
   $TLD_ip=substr(substr($TLD_ip,0,strlen($TLD_ip)-2),-3);
   $chk=split("\(",$TLD_ip);

   if(!$chk[1] && $TLD_ip != 'com' && $TLD_ip != 'net' && $TLD_ip != 'org' &&
                  $TLD_ip != 'edu' && $TLD_ip != 'gov' && $TLD_ip != '.ca' )   return true; 
// not allowed
   return false;
}

//
// Validate an e-mail address
//
function is_valid_email($email)
{
    if (strlen($email) > 50)           return false;

        if( TLD_check( substr($email,-3), $_SERVER["REMOTE_ADDR"] )) return false;

    return preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
}

18

(30 replies, posted in PunBB 1.2 discussion)

I edited the include/email.php

this works for me:

// Validate an e-mail address
//
function is_valid_email($email)
{
    if (strlen($email) > 50)
        return false;

// Allow primarily American TLDs only
$TLD3 = substr($email, -3);
if( $TLD3 != 'com' && $TLD3 != 'net' && $TLD3 != 'org' && $TLD3 != 'edu' && $TLD3 != 'gov'
                           && $TLD3 != '.ca' )
    return false;

// this also blocks lower tier USA TLDs .info .biz .us .name
 

    return preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
}

.:.

19

(98 replies, posted in News)

hcgtv wrote:

Due to the overwhelming love for the PunBB 1.2.x series, the release of 1.3 has been postponed wink

Apparently for at least a decade.

20

(3 replies, posted in Feature requests)

Hide/Unhide categories is useful but not the same thing.  On many message boards, users seek out a few forums spanning more than one category.  There is user discussion about this on one of the vBulletin forums I go to:

http://eforum.reviewjournal.com/lv/show … hp?t=10790

21

(3 replies, posted in Feature requests)

Like many, I suspect, I am still using PHPBB and "waiting for Godot ... I mean PunBB 1.3"

A lot of message boards have so many forums that it becomes cumbersome to quickly find the forums that a user prefers to participate in.  Is there a feature planned to hide/unhide individual forums per user so that a user can view a list of maybe 4 or 5 they use regularly and avoid wading through a list of 20 or 30 in which they have no interest?

There are other versions out there on the net, however, I just finished a webpage to generate javascript code to hide email addresses and phone numbers on web pages from the spambots. It is not meant to stop hackers (ok, maybe lazy ones) but it will enhance web privacy. It is also easy to use.

Generator: http://vegas215.com/antispam.html

Test Page: http://vegas215.com/antispamtest.html

http://www.mylvn.com/images/aspambot.gif

23

(7 replies, posted in Feature requests)

I've been running a low-volume neighborhood-oriented message board for the Las Vegas area.  I currently use PHPBB but I am likely to convert to PUNBB 1.2 for performance reasons.

http://my-las-vegas-neighborhood.com

Most of my users are relatively unsophisticated technically but would like to post events, etc. from other sites.  Copy and Paste are not always good options because events on other sites are either images or PDF files.

Using the optional <IFRAME width=100% height=500 src=XYZ> tag to access external sites solves this problem without incurring a performance hit.

I would hope that PUNBB 1.2 would also include this feature as a relatively simple way to embed external images, text, and web pages.