]> git.wincent.com - wikitext.git/commitdiff
Ensure ampersands in URIs are adequately entified
authorWincent Colaiuta <win@wincent.com>
Thu, 29 Nov 2012 08:25:49 +0000 (00:25 -0800)
committerWincent Colaiuta <win@wincent.com>
Thu, 29 Nov 2012 08:25:49 +0000 (00:25 -0800)
Fixes:

  https://wincent.com/issues/2010

Signed-off-by: Wincent Colaiuta <win@wincent.com>
ext/parser.c
spec/autolinking_spec.rb
spec/external_link_spec.rb

index e3f58976acefd69dfb8babc6904031870c24cdb4..00b8e324633b30dd324a0ee57d8ec76b22f6cb85 100644 (file)
@@ -440,13 +440,13 @@ void wiki_append_sanitized_link_target(str_t *link_target, str_t *output, bool t
 void wiki_append_hyperlink(parser_t *parser, VALUE link_prefix, str_t *link_target, str_t *link_text, VALUE link_class, VALUE link_rel, bool check_autolink)
 {
     if (check_autolink && !parser->autolink)
 void wiki_append_hyperlink(parser_t *parser, VALUE link_prefix, str_t *link_target, str_t *link_text, VALUE link_class, VALUE link_rel, bool check_autolink)
 {
     if (check_autolink && !parser->autolink)
-        str_append_str(parser->output, link_target);
+        wiki_append_sanitized_link_target(link_target, parser->output, true);
     else
     {
         str_append(parser->output, a_start, sizeof(a_start) - 1);               // <a href="
         if (!NIL_P(link_prefix))
             str_append_string(parser->output, link_prefix);
     else
     {
         str_append(parser->output, a_start, sizeof(a_start) - 1);               // <a href="
         if (!NIL_P(link_prefix))
             str_append_string(parser->output, link_prefix);
-        str_append_str(parser->output, link_target);
+        wiki_append_sanitized_link_target(link_target, parser->output, true);
 
         // special handling for mailto URIs
         const char *mailto = "mailto:";
 
         // special handling for mailto URIs
         const char *mailto = "mailto:";
@@ -469,7 +469,7 @@ void wiki_append_hyperlink(parser_t *parser, VALUE link_prefix, str_t *link_targ
         }
         str_append(parser->output, a_start_close, sizeof(a_start_close) - 1);   // ">
         if (!link_text || link_text->len == 0) // re-use link_target
         }
         str_append(parser->output, a_start_close, sizeof(a_start_close) - 1);   // ">
         if (!link_text || link_text->len == 0) // re-use link_target
-            str_append_str(parser->output, link_target);
+            wiki_append_sanitized_link_target(link_target, parser->output, true);
         else
             str_append_str(parser->output, link_text);
         str_append(parser->output, a_end, sizeof(a_end) - 1);                   // </a>
         else
             str_append_str(parser->output, link_text);
         str_append(parser->output, a_end, sizeof(a_end) - 1);                   // </a>
@@ -1978,9 +1978,13 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
 
             case URI:
                 if (IN(NO_WIKI_START))
 
             case URI:
                 if (IN(NO_WIKI_START))
+                {
                     // user can temporarily suppress autolinking by using <nowiki></nowiki>
                     // note that unlike MediaWiki, we do allow autolinking inside PRE blocks
                     // user can temporarily suppress autolinking by using <nowiki></nowiki>
                     // note that unlike MediaWiki, we do allow autolinking inside PRE blocks
-                    str_append(parser->output, token->start, TOKEN_LEN(token));
+                    token_str->ptr = token->start;
+                    token_str->len = TOKEN_LEN(token);
+                    wiki_append_sanitized_link_target(token_str, parser->output, false);
+                }
                 else if (IN(LINK_START))
                 {
                     // if the URI were allowed it would have been handled already in LINK_START
                 else if (IN(LINK_START))
                 {
                     // if the URI were allowed it would have been handled already in LINK_START
@@ -2017,7 +2021,11 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                         }
                     }
                     else
                         }
                     }
                     else
-                        str_append(parser->link_text, token->start, TOKEN_LEN(token));
+                    {
+                        token_str->ptr = token->start;
+                        token_str->len = TOKEN_LEN(token);
+                        wiki_append_sanitized_link_target(token_str, parser->link_text, false);
+                    }
                 }
                 else
                 {
                 }
                 else
                 {
index c0090941a4fda859421d09e6e6581e156db39d0f..67c9cf809e9a745a5e85538d3cd45273f2ff4d98 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
+# Copyright 2007-2012 Wincent Colaiuta. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -58,7 +58,12 @@ describe Wikitext::Parser, 'autolinking' do
       @parser.parse(uri).should == %Q{<p><a href="svn://example.com/" class="external">svn://example.com/</a></p>\n}
     end
 
       @parser.parse(uri).should == %Q{<p><a href="svn://example.com/" class="external">svn://example.com/</a></p>\n}
     end
 
-    it 'should apple the external_link_class CSS class if set' do
+    it 'converts ampersands into entities' do
+      expected = %{<p><a href="http://google.com/?q=1&amp;lang=en" class="external">http://google.com/?q=1&amp;lang=en</a></p>\n}
+      @parser.parse('http://google.com/?q=1&lang=en').should == expected
+    end
+
+    it 'should apply the external_link_class CSS class if set' do
       uri = 'http://example.com/'
       @parser.external_link_class = 'bar'
       @parser.parse(uri).should == %Q{<p><a href="http://example.com/" class="bar">http://example.com/</a></p>\n}
       uri = 'http://example.com/'
       @parser.external_link_class = 'bar'
       @parser.parse(uri).should == %Q{<p><a href="http://example.com/" class="bar">http://example.com/</a></p>\n}
index 4b7c99eafb385bfbae37b16ff173ea49cec77965..b106a69e39f46d92886898b9e4ee1cd12bd44381 100644 (file)
@@ -75,7 +75,16 @@ describe Wikitext::Parser, 'external links' do
     # more general case of bug reported here: https://wincent.com/issues/1955
     expected = %{<p><a href="http://google.com/?q=user@example.com" class="external">Google for user@example.com</a></p>\n}
     @parser.parse('[http://google.com/?q=user@example.com Google for user@example.com]').should == expected
     # more general case of bug reported here: https://wincent.com/issues/1955
     expected = %{<p><a href="http://google.com/?q=user@example.com" class="external">Google for user@example.com</a></p>\n}
     @parser.parse('[http://google.com/?q=user@example.com Google for user@example.com]').should == expected
+  end
+
+  it 'formats ampersands in link targets using entities' do
+    expected =%{<p><a href="http://google.com/?q=1&amp;lang=en" class="external">Google</a></p>\n}
+    @parser.parse('[http://google.com/?q=1&lang=en Google]').should == expected
+  end
 
 
+  it 'formats ampersands in URIs in link text' do
+    expected =%{<p><a href="http://google.com/?q=1&amp;lang=en" class="external">http://google.com/?q=1&amp;lang=en</a></p>\n}
+    @parser.parse('[http://google.com/?q=1&lang=en http://google.com/?q=1&lang=en]').should == expected
   end
 
   it 'should format absolute path links' do
   end
 
   it 'should format absolute path links' do