X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;ds=inline;f=blosxom.cgi;h=2c0054797a4cd61b85083cbfda9491cd259e5bba;hb=20572387b9318dc467ea2c3ac703993ce2537ed4;hp=d2c1c46b76d223381e9be3f48fd771656985f781;hpb=10beab43faade09fc0728590ff8c4ee81cd63994;p=matthijs%2Fupstream%2Fblosxom.git
diff --git a/blosxom.cgi b/blosxom.cgi
index d2c1c46..2c00547 100755
--- a/blosxom.cgi
+++ b/blosxom.cgi
@@ -1,8 +1,8 @@
#!/usr/bin/perl
# Blosxom
-# Author: Rael Dornfest (2002-2003), The Blosxom Development Team (2005-2008)
-# Version: 2.1.2 ($Id: blosxom.cgi,v 1.91 2009/03/08 00:58:52 xtaran Exp $)
+# Author: Rael Dornfest (2002-2003), The Blosxom Development Team (2005-2009)
+# Version: 2.1.2 ($Id: blosxom.cgi,v 1.98 2009/07/19 17:18:37 xtaran Exp $)
# Home/Docs/Licensing: http://blosxom.sourceforge.net/
# Development/Downloads: http://sourceforge.net/projects/blosxom
@@ -137,6 +137,16 @@ $static_entries = 0;
# this off if they do it themselves)
$encode_xml_entities = 1;
+# Should I encode 8 bit special characters, e.g. umlauts in URLs, e.g.
+# convert an ISO-Latin-1 \"o to %F6? (off by default for now; plugins
+# can change this, too)
+$encode_8bit_chars = 0;
+
+# RegExp matching all characters which should be URL encoded in links.
+# Defaults to anything but numbers, letters, slash, colon, dash,
+# underscore and dot.
+$url_escape_re = qr([^-/a-zA-Z0-9:._]);
+
# --------------------------------
=head1 ENVIRONMENT
@@ -185,9 +195,54 @@ development was picked up by a team of dedicated users of blosxom since
=cut
-
-use vars
- qw! $version $blog_title $blog_description $blog_language $blog_encoding $datadir $url %template $template $depth $num_entries $file_extension $default_flavour $static_or_dynamic $config_dir $plugin_list $plugin_path $plugin_dir $plugin_state_dir @plugins %plugins $static_dir $static_password @static_flavours $static_entries $path_info_full $path_info $path_info_yr $path_info_mo $path_info_da $path_info_mo_num $flavour $static_or_dynamic %month2num @num2month $interpolate $entries $output $header $show_future_entries %files %indexes %others $encode_xml_entities $content_type !;
+use vars qw!
+ $version
+ $blog_title
+ $blog_description
+ $blog_language
+ $blog_encoding
+ $datadir
+ $url
+ %template
+ $template
+ $depth
+ $num_entries
+ $file_extension
+ $default_flavour
+ $static_or_dynamic
+ $config_dir
+ $plugin_list
+ $plugin_path
+ $plugin_dir
+ $plugin_state_dir
+ @plugins
+ %plugins
+ $static_dir
+ $static_password
+ @static_flavours
+ $static_entries
+ $path_info_full
+ $path_info
+ $path_info_yr
+ $path_info_mo
+ $path_info_da
+ $path_info_mo_num
+ $flavour
+ %month2num
+ @num2month
+ $interpolate
+ $entries
+ $output
+ $header
+ $show_future_entries
+ %files
+ %indexes
+ %others
+ $encode_xml_entities
+ $encode_8bit_chars
+ $url_escape_re
+ $content_type
+ !;
use strict;
use FileHandle;
@@ -255,7 +310,7 @@ unless ($url) {
$url = url();
# Unescape %XX hex codes (from URI::Escape::uri_unescape)
- $url =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
+ $url =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
# Support being called from inside a SSI document
$url =~ s/^included:/http:/ if $ENV{SERVER_PROTOCOL} eq 'INCLUDED';
@@ -306,14 +361,14 @@ else {
# Path Info Magic
# Take a gander at HTTP's PATH_INFO for optional blog name, archive yr/mo/day
my @path_info = split m{/}, path_info() || param('path');
-$path_info_full = join '/', @path_info; # Equivalent to $ENV{PATH_INFO}
+$path_info_full = join '/', @path_info; # Equivalent to $ENV{PATH_INFO}
shift @path_info;
# Flavour specified by ?flav={flav} or index.{flav}
$flavour = '';
-if (! ($flavour = param('flav'))) {
+if ( !( $flavour = param('flav') ) ) {
if ( $path_info[$#path_info] =~ /(.+)\.(.+)$/ ) {
- $flavour = $2;
+ $flavour = $2;
pop @path_info if $1 eq 'index';
}
}
@@ -323,45 +378,50 @@ $flavour ||= $default_flavour;
$flavour = blosxom_html_escape($flavour);
sub blosxom_html_escape {
- my $string = shift;
- my %escape = (
- '<' => '<',
- '>' => '>',
- '&' => '&',
- '"' => '"',
- "'" => '''
- );
- my $escape_re = join '|' => keys %escape;
- $string =~ s/($escape_re)/$escape{$1}/g;
- $string;
+ my $string = shift;
+ my %escape = (
+ '<' => '<',
+ '>' => '>',
+ '&' => '&',
+ '"' => '"',
+ "'" => '''
+ );
+ my $escape_re = join '|' => keys %escape;
+ $string =~ s/($escape_re)/$escape{$1}/g;
+ $string;
}
# Global variable to be used in head/foot.{flavour} templates
$path_info = '';
+
# Add all @path_info elements to $path_info till we come to one that could be a year
-while ( $path_info[0] && $path_info[0] !~ /^(19|20)\d{2}$/) {
+while ( $path_info[0] && $path_info[0] !~ /^(19|20)\d{2}$/ ) {
$path_info .= '/' . shift @path_info;
}
# Pull date elements out of path
-if ($path_info[0] && $path_info[0] =~ /^(19|20)\d{2}$/) {
- $path_info_yr = shift @path_info;
- if ($path_info[0] &&
- ($path_info[0] =~ /^(0\d|1[012])$/ ||
- exists $month2num{ ucfirst lc $path_info_mo })) {
- $path_info_mo = shift @path_info;
- # Map path_info_mo to numeric $path_info_mo_num
- $path_info_mo_num = $path_info_mo =~ /^\d{2}$/
- ? $path_info_mo
- : $month2num{ ucfirst lc $path_info_mo };
- if ($path_info[0] && $path_info[0] =~ /^[0123]\d$/) {
- $path_info_da = shift @path_info;
+if ( $path_info[0] && $path_info[0] =~ /^(19|20)\d{2}$/ ) {
+ $path_info_yr = shift @path_info;
+ if ($path_info[0]
+ && ( $path_info[0] =~ /^(0\d|1[012])$/
+ || exists $month2num{ ucfirst lc $path_info_mo } )
+ )
+ {
+ $path_info_mo = shift @path_info;
+
+ # Map path_info_mo to numeric $path_info_mo_num
+ $path_info_mo_num
+ = $path_info_mo =~ /^\d{2}$/
+ ? $path_info_mo
+ : $month2num{ ucfirst lc $path_info_mo };
+ if ( $path_info[0] && $path_info[0] =~ /^[0123]\d$/ ) {
+ $path_info_da = shift @path_info;
+ }
}
- }
}
# Add remaining path elements to $path_info
-$path_info .= '/' . join('/', @path_info);
+$path_info .= '/' . join( '/', @path_info );
# Strip spurious slashes
$path_info =~ s!(^/*)|(/*$)!!g;
@@ -404,7 +464,7 @@ my @plugin_list = ();
my %plugin_hash = ();
# If $plugin_list is set, read plugins to use from that file
-if ( $plugin_list ) {
+if ($plugin_list) {
if ( -r $plugin_list and $fh->open("< $plugin_list") ) {
@plugin_list = map { chomp $_; $_ } grep { /\S/ && !/^#/ } <$fh>;
$fh->close;
@@ -416,7 +476,7 @@ if ( $plugin_list ) {
}
# Otherwise walk @plugin_dirs to get list of plugins to use
-if ( ! @plugin_list && @plugin_dirs ) {
+if ( !@plugin_list && @plugin_dirs ) {
for my $plugin_dir (@plugin_dirs) {
next unless -d $plugin_dir;
if ( opendir PLUGINS, $plugin_dir ) {
@@ -446,7 +506,7 @@ foreach my $plugin (@plugin_list) {
my $on_off = $off eq '_' ? -1 : 1;
# Allow perl module plugins
- # The -z test is a hack to allow a zero-length placeholder file in a
+ # The -z test is a hack to allow a zero-length placeholder file in a
# $plugin_path directory to indicate an @INC module should be loaded
if ( $plugin =~ m/::/ && ( $plugin_list || -z $plugin_hash{$plugin} ) ) {
@@ -490,6 +550,7 @@ sub load_template {
# Define default entries subroutine
$entries = sub {
my ( %files, %indexes, %others );
+ my $param_all = param('-all');
find(
sub {
my $d;
@@ -519,7 +580,7 @@ $entries = sub {
# static rendering bits
my $static_file
= "$static_dir/$1/index." . $static_flavours[0];
- if ( param('-all')
+ if ( $param_all
or !-f $static_file
or stat($static_file)->mtime < $mtime )
{
@@ -558,11 +619,7 @@ my ( $files, $indexes, $others ) = &$entries();
%indexes = %$indexes;
# Static
-if ( !$ENV{GATEWAY_INTERFACE}
- and param('-password')
- and $static_password
- and param('-password') eq $static_password )
-{
+if ( $static_or_dynamic eq 'static' ) {
param('-quiet') or print "Blosxom is generating static index pages...\n";
@@ -663,10 +720,13 @@ sub generate {
# Define default interpolation subroutine
$interpolate = sub {
+
package blosxom;
my $template = shift;
+
# Interpolate scalars, namespaced scalars, and hash/hashref scalars
- $template =~ s/(\$\w+(?:::\w+)*(?:(?:->)?{(['"]?)[-\w]+\2})?)/"defined $1 ? $1 : ''"/gee;
+ $template
+ =~ s/(\$\w+(?:::\w+)*(?:(?:->)?{([\'\"]?)[-\w]+\2})?)/"defined $1 ? $1 : ''"/gee;
return $template;
};
@@ -714,8 +774,7 @@ sub generate {
# Define a default sort subroutine
my $sort = sub {
my ($files_ref) = @_;
- return
- sort { $files_ref->{$b} <=> $files_ref->{$a} }
+ return sort { $files_ref->{$b} <=> $files_ref->{$a} }
keys %$files_ref;
};
@@ -801,18 +860,22 @@ sub generate {
}
}
- if ( $encode_xml_entities &&
- $content_type =~ m{\bxml\b} &&
- $content_type !~ m{\bxhtml\b} ) {
- # Escape special characters inside the container
+ # Save unescaped versions and allow them to be used in
+ # flavour templates.
+ use vars qw/$url_unesc $path_unesc $fn_unesc/;
+ $url_unesc = $url;
+ $path_unesc = $path;
+ $fn_unesc = $fn;
+
+ # Fix special characters in links inside XML content
+ if ( $encode_xml_entities
+ && $content_type =~ m{\bxml\b}
+ && $content_type !~ m{\bxhtml\b} )
+ {
- # The following line should be moved more towards to top for
- # performance reasons -- Axel Beckert, 2008-07-22
- my $url_escape_re = qr([^-/a-zA-Z0-9:._]);
+ # Escape special characters inside the container
- $url =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
- $path =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
- $fn =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
+ &url_escape_url_path_and_fn();
# Escape <, >, and &, and to produce valid RSS
$title = blosxom_html_escape($title);
@@ -822,6 +885,11 @@ sub generate {
$fn = blosxom_html_escape($fn);
}
+ # Fix special characters in links inside XML content
+ if ($encode_8bit_chars) {
+ &url_escape_url_path_and_fn();
+ }
+
$story = &$interpolate($story);
$output .= $story;
@@ -879,6 +947,12 @@ sub nice_date {
return ( $dw, $mo, $mo_num, $da, $ti, $yr, $utc_offset );
}
+sub url_escape_url_path_and_fn {
+ $url =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
+ $path =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
+ $fn =~ s($url_escape_re)(sprintf('%%%02X', ord($&)))eg;
+}
+
# Default HTML and RSS template bits
__DATA__
html content_type text/html; charset=$blog_encoding