avoid potential infinite loop in smiley expansion
authorJoey Hess <joey@gnu.kitenet.net>
Sun, 8 Mar 2009 22:46:18 +0000 (18:46 -0400)
committerJoey Hess <joey@gnu.kitenet.net>
Sun, 8 Mar 2009 22:49:34 +0000 (18:49 -0400)
- In 3.05, ikiwiki began expanding templates in scan mode,
  for annoying, expensive, but ultimatly necessary reasons
  of correctness.
- Smiley processing has a bug: It inserts a span for the smiley,
  and then continues searching forward in the content for more,
  starting at $end_of_smiley+1. Which means it searches for smilies
  in the span too! And if it somehow finds one, we get an infinite loop
  here.
- This bug can, probably, only be tickled if a htmllink to
  show the smiley fails, because the smiley file doesn't exist,
  or because ikiwiki doesn't know about it. In that case,
  a link will be inserted to _create_ the missing page,
  and that link will include the smiley inside the <a></a>.
- When a template is expanded in scan mode, and it contains
  an inline, the sanitize hook is run during scan mode,
  which never happened before. That causes the smiley processor
  to run, before ikiwiki is, necessarily, aware that all
  the smiley files exist (depending on scan order). So
  it inserts creation links for them, and triggers the bug.

I've put in the simple fix of jumping forward past the inserted
span, and it does fix the problem. I will need to look in a bit
more detail into why an inline nested inside a template is
fully expanded during the scan pass -- that really shouldn't
be necessary, and it makes things much slower than they need
to be.

IkiWiki/Plugin/smiley.pm
debian/changelog

index 1697a37c1981d0520f1966a53cd647324fcb2ba8..0d77916d0d3d633e7656d79527cce12647089d47 100644 (file)
@@ -87,10 +87,10 @@ MATCH:      while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) {
                }
                else {
                        # Replace the smiley with its expanded value.
-                       substr($_, $spos, length($smiley))=
-                               htmllink($params{page}, $params{destpage},
+                       my $link=htmllink($params{page}, $params{destpage},
                                         $smileys{$smiley}, linktext => $smiley);
-                       pos=$epos+1;
+                       substr($_, $spos, length($smiley))=$link;
+                       pos=$epos+length($link);
                }
        }
 
index d6ee6fd8a75d48d4046670d99bcf5bff78c4a720..e5d52220079dc39c3256343ca88d5633406cb56d 100644 (file)
@@ -4,6 +4,7 @@ ikiwiki (3.07) UNRELEASED; urgency=low
   * Updated French translation (Jean-Luc Coulon). Closes: #518510
   * wmd: New plugin contributed by William Uther to support the WMD
     Wysiwym markdown editor.
+  * smiley: Avoid infinite loop in smiley expansion. Closes: #518805
 
  -- Joey Hess <joeyh@debian.org>  Thu, 05 Mar 2009 15:43:02 -0500