Update of /cvs/scoop/scoop/lib/Scoop/Stories
In directory lithium.sabren.com:/tmp/cvs-serv30231/lib/Scoop/Stories

Modified Files:
	Elements.pm List.pm Submit.pm 
Log Message:
Committing XSS (and some others janra found, as I recall) security fixes 
and some stuff found in the K5 upgrade. -j


Index: Elements.pm
===================================================================
RCS file: /cvs/scoop/scoop/lib/Scoop/Stories/Elements.pm,v
retrieving revision 1.129
retrieving revision 1.130
diff -C2 -d -r1.129 -r1.130
*** Elements.pm	13 Mar 2006 07:49:59 -0000	1.129
--- Elements.pm	6 Aug 2006 04:22:47 -0000	1.130
***************
*** 79,83 ****
  	}
  
! 	if ($story->{displaystatus} == '-1') {
  		unless ($S->have_perm('moderate') || 
                          ($S->{UID} eq $story->{'aid'} && $S->have_perm('edit_my_stories')) || 
--- 79,83 ----
  	}
  
! 	if ($story->{displaystatus} < -1) {
  		unless ($S->have_perm('moderate') || 
                          ($S->{UID} eq $story->{'aid'} && $S->have_perm('edit_my_stories')) || 
***************
*** 89,92 ****
--- 89,99 ----
  	}
  
+ 	if ($story->{displaystatus} == -1) {
+ 		unless ($S->have_perm('story_admin') || $S->{UID} eq $story->{'aid'}) {
+                         $page = '';
+ 		}
+ 	}
+ 
+ 
  	return ($story, $page);
  }		
***************
*** 271,274 ****
--- 278,283 ----
  		push(@where, "sid = '$args->{-sid}'") if exists($args->{'-sid'});
  		push(@where, $excl_sect_sql) if ($excl_sect_sql ne '');
+                 my $idx;
+                 $idx = 'use index (time_idx)' unless exists($args->{'-sid'});
  		push(@where, $args->{-where}) if ($args->{-where});
  
***************
*** 351,358 ****
--- 360,370 ----
  		my ($where, $limit);
  		
+ 		$limit = qq{$S->pref('maxstories'), $S->pref('maxtitles')};
+ 		my $idx; #= 'use index (time_idx)';
  		if ($args->{'-sid'}) {
  			my $sid = $S->dbh->quote($args->{'-sid'});
  			$where = qq|sid = $sid AND |;
  			$limit = '';
+ 			$idx = '';
  		}
  		if (defined($args->{'-section'})) {
***************
*** 362,366 ****
  				$args->{'-section'} = $1;
  			}
! 			$where .= qq|section $operator \'$args->{'-section'}\' AND |;
  		}
  		if (defined($args->{'-topic'})) {
--- 374,379 ----
  				$args->{'-section'} = $1;
  			}
! 			$where .= qq|section $operator "$args->{'-section'}" AND |;
! 			$idx = 'use index (time_idx)';
  		}
  		if (defined($args->{'-topic'})) {
***************
*** 370,374 ****
  				$args->{'-topic'} = $1;
  			}
! 			$where .= qq|tid $operator \'$args->{'-topic'}\' AND |;
  		}
  		
--- 383,388 ----
  				$args->{'-topic'} = $1;
  			}
! 			$where .= qq|tid $operator "$args->{'-topic'}" AND |;
!                         $idx = 'use index (tid_st_idx)';
  		}
  		
***************
*** 387,391 ****
  			ARCHIVE => $archive,
  			WHAT  => qq{sid, title, $wmd_format AS ftime},
! 			FROM  => q{stories},
  			WHERE => $where,
  			LIMIT => $S->pref('maxtitles'),
--- 401,405 ----
  			ARCHIVE => $archive,
  			WHAT  => qq{sid, title, $wmd_format AS ftime},
! 			FROM  => qq{stories $idx},
  			WHERE => $where,
  			LIMIT => $S->pref('maxtitles'),
***************
*** 394,402 ****
  		});
  	} elsif ($type eq 'titlesonly-section') {
  		($rv, $sth) = $S->db_select({
  			ARCHIVE => $archive,
  			DEBUG => $DEBUG,
  			WHAT  => qq{sid, title, $wmd_format AS ftime},
! 			FROM  => q{stories},
  			WHERE => q{displaystatus >= 0 AND section = 'section' $excl_sect_sql_wAND},
  			LIMIT => $S->pref('maxtitles'),
--- 408,417 ----
  		});
  	} elsif ($type eq 'titlesonly-section') {
+ 		my $idx = 'use index (time_idx)';
  		($rv, $sth) = $S->db_select({
  			ARCHIVE => $archive,
  			DEBUG => $DEBUG,
  			WHAT  => qq{sid, title, $wmd_format AS ftime},
! 			FROM  => "stories $idx",
  			WHERE => q{displaystatus >= 0 AND section = 'section' $excl_sect_sql_wAND},
  			LIMIT => $S->pref('maxtitles'),
***************
*** 437,440 ****
--- 452,457 ----
  		$sec_where .= ' ' . $excl_sect_sql_wAND;
  
+                 my $idx = ($topic) ? 'use index (tid_st_idx)' : 'use index (time_idx)';
+ 
  		my $maxstories = $S->pref('maxstories');
  		my $offset = (($page * $maxstories) - $maxstories) if $page;
***************
*** 584,587 ****
--- 601,611 ----
  This is a true/false flag only.
  
+ =item skip_archive
+ 
+ When true, ignore the archive db even if the number of stories returned is less
+ than the limit requested (or the default limit if not specified). If there is
+ no archive db configured, this flag is not necessary. This is a true/false flag
+ only.
+ 
  =item page
  
***************
*** 667,670 ****
--- 691,699 ----
  parameter is true) the viewed_stories table is aliased to 'v'.
  
+ =item debug
+ 
+ If true, turns on debugging output for this function. Look for it in your
+ error_log. This is a true/false flag only.
+ 
  =back
  
***************
*** 680,688 ****
  	my $sids;
  	my $q_uid = $S->dbh->quote($S->{UID});
  
  	warn "(get_sids) starting..." if $DEBUG;
  
  	#aid overrules user
! 	$params->{aid} = $S->get_uid_from_nick($params->{user}) if ($params->{user} && !$params->{aid});
  
  	# set up the SQL query
--- 709,723 ----
  	my $sids;
  	my $q_uid = $S->dbh->quote($S->{UID});
+ 	my $DEBUG = $params->{debug};
+ 
  
  	warn "(get_sids) starting..." if $DEBUG;
  
  	#aid overrules user
! 	if (!$params->{aid} && $params->{user} && ref($params->{user}) eq 'ARRAY') {
! 		@{$params->{aid}} = map {$S->get_uid_from_nick($_)} (@{$params->{user}});
! 	} elsif (!$params->{aid} && $params->{user}) {
! 		$params->{aid} = $S->get_uid_from_nick($params->{user});
! 	}
  
  	# set up the SQL query
***************
*** 719,723 ****
          }
  	$where = $disallowed_sections;
! 	$where .= ( $where && $excl_from_all ) ? ' AND ' : '';
  	$where .= $excl_from_all;
  
--- 754,758 ----
          }
  	$where = $disallowed_sections;
! #	$where .= ( $where && $excl_from_all ) ? ' AND ' : '';
  	$where .= $excl_from_all;
  
***************
*** 746,750 ****
  	}
  	
! 	$where .= $params->{where} if $params->{where};
  	$from .= " " . $params->{from} if $params->{from};
  
--- 781,785 ----
  	}
  	
! 	$where .= " AND $params->{where}" if $params->{where};
  	$from .= " " . $params->{from} if $params->{from};
  
***************
*** 774,779 ****
  	$sth->finish();
  
  	#FIXME don't forget the archive!
! 	if ( ($fetched < $limit || $limit == 0) && $S->{HAVE_ARCHIVE} ) {
  		warn "(get_sids) didn't get all the stories... checking archive db" if $DEBUG;
                  my $archfrom = "stories s";
--- 809,815 ----
  	$sth->finish();
  
+ 	warn "(get_sids) got $fetched stories." if $DEBUG;
  	#FIXME don't forget the archive!
! 	if ( ($fetched < $limit || $limit == 0) && $S->{HAVE_ARCHIVE} && !$params->{skip_archive} ) {
  		warn "(get_sids) didn't get all the stories... checking archive db" if $DEBUG;
                  my $archfrom = "stories s";
***************
*** 796,799 ****
--- 832,836 ----
  		$sth->finish();
  		my $newoffset = $offset - $maxoffset + $fetched;
+ 		my $newlimit = ($limit) ? $limit - $fetched : 0;
  
  		my $newfrom = $from;
***************
*** 813,817 ****
  			WHERE => $where,
  			ORDER_BY => 's.time desc',
! 			LIMIT => $limit,
  			OFFSET => $newoffset
  		});
--- 850,854 ----
  			WHERE => $where,
  			ORDER_BY => 's.time desc',
! 			LIMIT => $newlimit,
  			OFFSET => $newoffset
  		});
***************
*** 823,827 ****
  	}
  
! 	if ( $sids ) { warn "(get_sids) returning " . join(', ', @$sids) if $DEBUG; }
  
  	return $sids;
--- 860,864 ----
  	}
  
! 	if ( $sids ) { warn "(get_sids) returning " . @$sids . " stories: " . join(', ', @$sids) if $DEBUG; }
  
  	return $sids;
***************
*** 849,856 ****
  		# build the SQL query for those stories not in the cache
  		my $date_format = $S->date_format('time');
! 			
  		my ($rv,$sth) = $S->db_select({
  			DEBUG => $DEBUG,
! 			WHAT => "s.*,v.hotlisted,v.lastseen,v.highest_idx,u.nickname as nick,$date_format as ftime,count(c.cid) as comments",
  			FROM => "stories s LEFT JOIN ${main_db}.users u ON s.aid = u.uid LEFT JOIN ${main_db}.viewed_stories v ON (s.sid = v.sid AND v.uid = $q_uid) LEFT JOIN comments c ON s.sid = c.sid",
  			WHERE => "s.sid IN ($sids_sql)",
--- 886,893 ----
  		# build the SQL query for those stories not in the cache
  		my $date_format = $S->date_format('time');
! 		my $wmdformat = $S->date_format('time', 'WMD');			
  		my ($rv,$sth) = $S->db_select({
  			DEBUG => $DEBUG,
! 			WHAT => "s.*,v.hotlisted,v.lastseen,v.highest_idx,u.nickname as nick,$date_format as ftime,$wmdformat as wmdtime,count(c.cid) as comments",
  			FROM => "stories s LEFT JOIN ${main_db}.users u ON s.aid = u.uid LEFT JOIN ${main_db}.viewed_stories v ON (s.sid = v.sid AND v.uid = $q_uid) LEFT JOIN comments c ON s.sid = c.sid",
  			WHERE => "s.sid IN ($sids_sql)",
***************
*** 879,887 ****
  		# build the SQL query for those stories not in the cache
  		my $date_format = $S->date_format('time');
                  my $db_name = $S->{CONFIG}->{db_name} . ".users";
                  my ($rv,$sth) = $S->db_select({
                          DEBUG => $DEBUG,
                          ARCHIVE => 1,
!                         WHAT => "s.*,v.hotlisted,v.lastseen,v.highest_idx,u.nickname as nick,$date_format as ftime,count(c.cid) as comments",
                          FROM => "stories s LEFT JOIN $db_name u ON s.aid = u.uid LEFT JOIN ${main_db}.viewed_stories v ON (s.sid = v.sid AND v.uid = $q_uid) LEFT JOIN comments c ON s.sid = c.sid",
                          WHERE => "s.sid IN ($sids_sql)",
--- 916,925 ----
  		# build the SQL query for those stories not in the cache
  		my $date_format = $S->date_format('time');
+                 my $wmdformat = $S->date_format('time', 'WMD');
                  my $db_name = $S->{CONFIG}->{db_name} . ".users";
                  my ($rv,$sth) = $S->db_select({
                          DEBUG => $DEBUG,
                          ARCHIVE => 1,
!                         WHAT => "s.*,v.hotlisted,v.lastseen,v.highest_idx,u.nickname as nick,$date_format as ftime,$wmdformat as wmdtime,count(c.cid) as comments",
                          FROM => "stories s LEFT JOIN $db_name u ON s.aid = u.uid LEFT JOIN ${main_db}.viewed_stories v ON (s.sid = v.sid AND v.uid = $q_uid) LEFT JOIN comments c ON s.sid = c.sid",
                          WHERE => "s.sid IN ($sids_sql)",
***************
*** 1069,1073 ****
  	#If we're go to moderate this one....
  	if ($disp_mode eq 'moderate') {
! 		if ( $S->vars('story_auto_vote_zero') ) {
  			$S->save_vote ($sid, '0', 'N');
  		} else {
--- 1107,1111 ----
  	#If we're go to moderate this one....
  	if ($disp_mode eq 'moderate') {
! 		if ( $S->var('story_auto_vote_zero') ) {
  			$S->save_vote ($sid, '0', 'N');
  		} else {
***************
*** 1220,1226 ****
--- 1258,1266 ----
  		my $edit_button;
  		my $edit_instructions;
+ 		my $preview;
  		if ($story->{displaystatus} == '-3') {
  			$edit_button = '<INPUT TYPE="Submit" NAME="edit" VALUE="Edit Story">';
  			$edit_instructions = $S->{UI}->{BLOCKS}->{author_edit_instructions};
+ 			$preview = qq|<INPUT TYPE="hidden" NAME="preview" VALUE="1">|;
  		};
  		
***************
*** 1240,1244 ****
  				<INPUT TYPE="hidden" NAME="op" VALUE="submitstory">
  				<INPUT TYPE="hidden" NAME="sid" VALUE="$story->{sid}">
! 				<INPUT TYPE="hidden" NAME="preview" VALUE="1">
  				<INPUT TYPE="hidden" NAME="tid" VALUE="$story->{tid}">
  				<INPUT TYPE="hidden" NAME="title" VALUE="$story->{title}">
--- 1280,1284 ----
  				<INPUT TYPE="hidden" NAME="op" VALUE="submitstory">
  				<INPUT TYPE="hidden" NAME="sid" VALUE="$story->{sid}">
! 				$preview
  				<INPUT TYPE="hidden" NAME="tid" VALUE="$story->{tid}">
  				<INPUT TYPE="hidden" NAME="title" VALUE="$story->{title}">

Index: Submit.pm
===================================================================
RCS file: /cvs/scoop/scoop/lib/Scoop/Stories/Submit.pm,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** Submit.pm	14 Oct 2005 20:07:09 -0000	1.19
--- Submit.pm	6 Aug 2006 04:22:47 -0000	1.20
***************
*** 52,65 ****
  	my $guidelines = $S->{UI}->{BLOCKS}->{submission_guidelines};
  	
- 	if ($S->cgi->param('section') ne 'Diary') {
- 		$guidelines = $S->{UI}->{BLOCKS}->{diary_guidelines};
- 	}
- 	
  	my $form = $S->edit_story_form('public');
  	
- 	unless ($preview) {
- 		$form =~ s/%%guidelines%%/$guidelines/g;
- 	}
- 		
  	return ($content, $form);
  }
--- 52,57 ----

Index: List.pm
===================================================================
RCS file: /cvs/scoop/scoop/lib/Scoop/Stories/List.pm,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** List.pm	6 Oct 2005 20:14:45 -0000	1.9
--- List.pm	6 Aug 2006 04:22:47 -0000	1.10
***************
*** 276,283 ****
  sub _list_modsub {
  	my $S = shift;
! 	my $limit = shift;
! 	my $get_num = shift;
  	
! 	my ($content, $select);
  	my $dateformat = $S->date_format( 'time', 'short' );
  	my $hidescore = $S->{UI}->{VARS}->{hide_story_threshold};
--- 276,283 ----
  sub _list_modsub {
  	my $S = shift;
! 	my $limit; #= shift;
! 	my $get_num = 10000000; #shift;
  	
! 	my ($content, $select, $vote_queue, $edit_queue);
  	my $dateformat = $S->date_format( 'time', 'short' );
  	my $hidescore = $S->{UI}->{VARS}->{hide_story_threshold};
***************
*** 287,302 ****
  
  	$select = {
! 		WHAT => "sid, aid, users.nickname AS nick, tid, $dateformat as ftime, title, stories.score AS score, section",
! 		FROM => 'stories LEFT JOIN users ON stories.aid = users.uid',
  		WHERE => "((displaystatus = -2 AND stories.score > $hidescore) OR displaystatus = -3) AND $excl_sect_sql",
  		LIMIT => "$limit",
  		ORDER_BY => 'time DESC'};
  	
  	if ( $S->{UI}->{VARS}->{show_threshold} ) { $content .= $S->_show_threshold_text; }
! 	
! 	$content .= qq|
  		<TR><TD COLSPAN=4>&nbsp;</TD></TR>
  		<TR BGCOLOR="%%title_bgcolor%%">
! 		<TD valign="top">%%title_font%%<B>Title (topic)</B>%%title_font_end%%</TD>
  		<TD valign="top">%%title_font%%<B>Date</B>%%title_font_end%%</TD>
  		<TD align="center" valign="top">%%title_font%%<B>Author</B>%%title_font_end%%</TD>
--- 287,307 ----
  
  	$select = {
! 		WHAT => "stories.sid, aid, users.nickname AS nick, tid, $dateformat as ftime, title, stories.score AS score, section, count(comments.cid) as comments",
! 		FROM => 'stories LEFT JOIN users ON stories.aid = users.uid LEFT JOIN comments on stories.sid = comments.sid',
  		WHERE => "((displaystatus = -2 AND stories.score > $hidescore) OR displaystatus = -3) AND $excl_sect_sql",
  		LIMIT => "$limit",
+ 		GROUP_BY => 'stories.sid',
  		ORDER_BY => 'time DESC'};
  	
  	if ( $S->{UI}->{VARS}->{show_threshold} ) { $content .= $S->_show_threshold_text; }
! 
! 	my $topic = '';
! 	$topic = ' (topic)' if $S->var('use_topics');
! 
! 	$vote_queue = qq|
  		<TR><TD COLSPAN=4>&nbsp;</TD></TR>
+ 		<TR><TD COLSPAN=4>%%title_font%%<B>Stories currently in voting:</b>%%title_font_end%%</TD></TR>
  		<TR BGCOLOR="%%title_bgcolor%%">
! 		<TD valign="top">%%title_font%%<B>Title$topic</B>%%title_font_end%%</TD>
  		<TD valign="top">%%title_font%%<B>Date</B>%%title_font_end%%</TD>
  		<TD align="center" valign="top">%%title_font%%<B>Author</B>%%title_font_end%%</TD>
***************
*** 304,307 ****
--- 309,322 ----
  		</TR>|;
  
+ 	$edit_queue = qq|
+                 <TR><TD COLSPAN=4>&nbsp;</TD></TR>
+                 <TR><TD COLSPAN=4>%%title_font%%<B>Stories currently in editing:</b>%%title_font_end%%</TD></TR>
+                 <TR BGCOLOR="%%title_bgcolor%%">
+                 <TD valign="top">%%title_font%%<B>Title$topic</B>%%title_font_end%%</TD>
+                 <TD valign="top">%%title_font%%<B>Date</B>%%title_font_end%%</TD>
+                 <TD align="center" valign="top">%%title_font%%<B>Author</B>%%title_font_end%%</TD>
+                 <TD valign="top">%%title_font<B>Score</B>title_font_end%%</TD>
+                 </TR>|;
+ 
  	my ($tid, $section, $color, $story, $story_num, $displaystatus, $edit_link, $comment_count, $mod_set, $story_link, $info, $story_read_link, $i);
  	
***************
*** 309,316 ****
  	$story = $sth->fetchrow_hashref;
  	$i = 1;
! 	
  	while ($story && ($i <= $get_num) ) {
  		
! 		$story_link = "displaystory/$story->{sid}";
  		my ($disp_mode, $stuff) = $S->_mod_or_show($story->{sid});
  
--- 324,333 ----
  	$story = $sth->fetchrow_hashref;
  	$i = 1;
! 	my $vote_i = 1;
! 	my $edit_i = 1;
!         warn "Building modsub list\n";
  	while ($story && ($i <= $get_num) ) {
  		
! 		$story_link = "story/$story->{sid}";
  		my ($disp_mode, $stuff) = $S->_mod_or_show($story->{sid});
  
***************
*** 326,330 ****
  		}
  		
! 		$info = "Section: $S->{SECTION_DATA}->{$story->{section}}->{title}, Topic: $S->{TOPIC_DATA}->{$story->{tid}}->{alttext}";
  
  		if ($displaystatus == -1) {
--- 343,348 ----
  		}
  		
! 		$info = "Section: $S->{SECTION_DATA}->{$story->{section}}->{title}";
! 		$info .= ", Topic: $S->{TOPIC_DATA}->{$story->{tid}}->{alttext}" if $S->var('use_topics');
  
  		if ($displaystatus == -1) {
***************
*** 349,362 ****
  		
  		$story_num = ((($S->{CGI}->param('page') || 1)-1) * $get_num) + $i;
  
! 		$story->{nick} = $S->{UI}->{VARS}->{anon_user_nick} if $story->{aid} == -1;
! 
! 		$content .= qq|
! 		<TR$color>
! 			<TD valign="top">%%norm_font%%$story_num) <A HREF="%%rootdir%%/$story_link">$story->{title}</A>$story_read_link<BR>$info%%norm_font_end%%</TD>
! 			<TD valign="top">%%norm_font%%$story->{ftime}%%norm_font_end%%</TD>
! 			<TD align="center" valign="top">%%norm_font%%$story->{nick}%%norm_font_end%%</TD>
! 			<TD align="right" valign="top">%%norm_font%%$edit_link%%norm_font_end%%</TD>
! 		</TR>|;
  		$i = $i+1;
  		$story = $sth->fetchrow_hashref;
--- 367,393 ----
  		
  		$story_num = ((($S->{CGI}->param('page') || 1)-1) * $get_num) + $i;
+         $story->{nick} = $S->{UI}->{VARS}->{anon_user_nick} if $story->{aid} == -1;
  
! 		if ($displaystatus == -3) {
!                         $edit_queue .= qq|
!                         <TR$color>
!                                 <TD valign="top">%%norm_font%%$edit_i) <A HREF="%%rootdir%%/$story_link">$story->{title}</A> ($story->{comments} comments)$story_read_link
!                                 <BR>$info%%norm_font_end%%</TD>
!                                 <TD valign="top">%%norm_font%%$story->{ftime}%%norm_font_end%%</TD>
!                                 <TD align="center" valign="top">%%norm_font%%$story->{nick}%%norm_font_end%%</TD>
!                                 <TD valign="top">%%norm_font%%$edit_link%%norm_font_end%%</TD>
!                         </TR>|;
!                         $edit_i++;
!         } else {
!                         $vote_queue .= qq|
!                         <TR$color>
!                                 <TD valign="top">%%norm_font%%$vote_i) <A HREF="%%rootdir%%/$story_link">$story->{title}</A> ($story->{comments} comments)$story_read_link
!                                 <BR>$info%%norm_font_end%%</TD>
!                                 <TD valign="top">%%norm_font%%$story->{ftime}%%norm_font_end%%</TD>
!                                 <TD align="center" valign="top">%%norm_font%%$story->{nick}%%norm_font_end%%</TD>
!                                 <TD valign="top">%%norm_font%%$edit_link%%norm_font_end%%</TD>
!                         </TR>|;
!                         $vote_i++;
!         }
  		$i = $i+1;
  		$story = $sth->fetchrow_hashref;
***************
*** 364,367 ****
--- 395,399 ----
  	$sth->finish;
  	
+ 	$content .= $vote_queue . $edit_queue;	
  	return ($rv, $content);
  }