]> git.wincent.com - wikitext.git/commitdiff
Eat trailing space while encoding link targets
authorWincent Colaiuta <win@wincent.com>
Wed, 6 Feb 2008 14:20:44 +0000 (15:20 +0100)
committerWincent Colaiuta <win@wincent.com>
Wed, 6 Feb 2008 14:20:44 +0000 (15:20 +0100)
Similar commit for link sanitization to follow.

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

index 00d06ff7d3f93bffae80a702f8d98d1edf13d00b..bbe3abaf74890e1d3710899c9cc2f07fbb5075e4 100644 (file)
@@ -513,7 +513,7 @@ inline static VALUE _Wikitext_parser_encode_link_target(VALUE self, VALUE in)
     long        dest_len    = len * 2;
     char        *dest       = ALLOC_N(char, dest_len);
     char        *dest_ptr   = dest; // hang on to this so we can pass it to free() later
-
+    char        *non_space  = dest; // remember last non-space character output
     for (; input < end; input++)
     {
         if ((dest + 3) > (dest_ptr + dest_len))     // worst case: a single character may grow to 3 characters once encoded
@@ -541,17 +541,28 @@ inline static VALUE _Wikitext_parser_encode_link_target(VALUE self, VALUE in)
             (*input == '_') ||
             (*input == '.') ||
             (*input == '~'))
-            *dest++ = *input;
+        {
+            *dest++     = *input;
+            non_space   = dest;
+        }
         else if (*input == ' ' && input == start)
             start++;                    // we eat leading space
         else    // everything else gets URL-encoded
         {
-            *dest++ = '%';
-            *dest++ = hex[(unsigned char)(*input) / 16];   // left
-            *dest++ = hex[(unsigned char)(*input) % 16];   // right
+            *dest++     = '%';
+            *dest++     = hex[(unsigned char)(*input) / 16];   // left
+            *dest++     = hex[(unsigned char)(*input) % 16];   // right
+            if (*input != ' ')
+                non_space = dest;
         }
     }
-    VALUE out = rb_str_new(dest_ptr, dest - dest_ptr);
+
+    // trim trailing space if necessary
+    if (len> 0 && dest - 1 != non_space)
+        dest_len = non_space - dest_ptr;
+    else
+        dest_len = dest - dest_ptr;
+    VALUE out = rb_str_new(dest_ptr, dest_len);
     free(dest_ptr);
     return out;
 }
index a42bab6b64b417923241e500a7b92dc1625baab5..3e004ea3849d249f0d42f409c23503c85c623588 100755 (executable)
@@ -37,6 +37,13 @@ describe Wikitext, 'encoding a link target' do
     Wikitext::Parser.encode_link_target('    hello world').should == 'hello%20world'
   end
 
+  it 'should eat trailing spaces' do
+    Wikitext::Parser.encode_link_target('hello world ').should == 'hello%20world'
+    Wikitext::Parser.encode_link_target('hello world  ').should == 'hello%20world'
+    Wikitext::Parser.encode_link_target('hello world   ').should == 'hello%20world'
+    Wikitext::Parser.encode_link_target('hello world    ').should == 'hello%20world'
+  end
+
   it 'should convert reserved symbols into percent escapes' do
     Wikitext::Parser.encode_link_target('http://www.apple.com/q?foo').should == 'http%3a%2f%2fwww.apple.com%2fq%3ffoo'
   end