rinku 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +2 -1
- data/ext/rinku/rinku.c +11 -5
- data/lib/rails_rinku.rb +2 -1
- data/rinku.gemspec +1 -4
- data/test/autolink_test.rb +12 -9
- metadata +2 -5
- data/ext/rinku/houdini.h +0 -28
- data/ext/rinku/houdini_href_e.c +0 -108
- data/ext/rinku/houdini_html_e.c +0 -84
data/README.markdown
CHANGED
@@ -89,7 +89,8 @@ Rinku is written by me
|
|
89
89
|
----------------------
|
90
90
|
|
91
91
|
I am Vicent Marti, and I wrote Rinku.
|
92
|
-
While Rinku is busy doing autolinks, you should be busy following me on twitter.
|
92
|
+
While Rinku is busy doing autolinks, you should be busy following me on twitter.
|
93
|
+
[`@tanoku`](http://twitter.com/tanoku). Do it.
|
93
94
|
|
94
95
|
Rinku has an awesome license
|
95
96
|
----------------------------
|
data/ext/rinku/rinku.c
CHANGED
@@ -26,7 +26,6 @@
|
|
26
26
|
|
27
27
|
#include "autolink.h"
|
28
28
|
#include "buffer.h"
|
29
|
-
#include "houdini.h"
|
30
29
|
|
31
30
|
#include <string.h>
|
32
31
|
#include <stdlib.h>
|
@@ -73,9 +72,9 @@ static const char *g_hrefs[] = {
|
|
73
72
|
};
|
74
73
|
|
75
74
|
static void
|
76
|
-
|
75
|
+
autolink__print(struct buf *ob, const struct buf *link, void *payload)
|
77
76
|
{
|
78
|
-
|
77
|
+
bufput(ob, link->data, link->size);
|
79
78
|
}
|
80
79
|
|
81
80
|
/* From sundown/html/html.c */
|
@@ -187,7 +186,7 @@ rinku_autolink(
|
|
187
186
|
}
|
188
187
|
|
189
188
|
if (link_text_cb == NULL)
|
190
|
-
link_text_cb = &
|
189
|
+
link_text_cb = &autolink__print;
|
191
190
|
|
192
191
|
if (link_attr != NULL) {
|
193
192
|
while (isspace(*link_attr))
|
@@ -228,7 +227,7 @@ rinku_autolink(
|
|
228
227
|
bufput(ob, text + i, end - i - rewind);
|
229
228
|
|
230
229
|
bufputs(ob, g_hrefs[(int)action]);
|
231
|
-
|
230
|
+
bufput(ob, link->data, link->size);
|
232
231
|
|
233
232
|
if (link_attr) {
|
234
233
|
BUFPUTSL(ob, "\" ");
|
@@ -277,6 +276,13 @@ autolink_callback(struct buf *link_text, const struct buf *link, void *block)
|
|
277
276
|
* Parses a block of text looking for "safe" urls or email addresses,
|
278
277
|
* and turns them into HTML links with the given attributes.
|
279
278
|
*
|
279
|
+
* NOTE: The block of text may or may not be HTML; if the text is HTML,
|
280
|
+
* Rinku will skip the relevant tags to prevent double-linking and linking
|
281
|
+
* inside `pre` blocks by default.
|
282
|
+
*
|
283
|
+
* NOTE: If the input text is HTML, it's expected to be already escaped.
|
284
|
+
* Rinku will perform no escaping.
|
285
|
+
*
|
280
286
|
* NOTE: Currently the follow protocols are considered safe and are the
|
281
287
|
* only ones that will be autolinked.
|
282
288
|
*
|
data/lib/rails_rinku.rb
CHANGED
@@ -10,8 +10,9 @@ module RailsRinku
|
|
10
10
|
options[:html] = args[1] || {}
|
11
11
|
end
|
12
12
|
options.reverse_merge!(:link => :all, :html => {})
|
13
|
+
text = text.html_safe unless text.html_safe?
|
13
14
|
|
14
|
-
Rinku.auto_link(text, options[:link], tag_options(options[:html]), &block)
|
15
|
+
Rinku.auto_link(text.html_safe, options[:link], tag_options(options[:html]), &block)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
data/rinku.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rinku'
|
3
|
-
s.version = '1.
|
3
|
+
s.version = '1.4.0'
|
4
4
|
s.summary = "Mostly autolinking"
|
5
5
|
s.description = <<-EOF
|
6
6
|
A fast and very smart autolinking library that
|
@@ -20,9 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
ext/rinku/buffer.c
|
21
21
|
ext/rinku/buffer.h
|
22
22
|
ext/rinku/extconf.rb
|
23
|
-
ext/rinku/houdini.h
|
24
|
-
ext/rinku/houdini_href_e.c
|
25
|
-
ext/rinku/houdini_html_e.c
|
26
23
|
lib/rinku.rb
|
27
24
|
lib/rails_rinku.rb
|
28
25
|
rinku.gemspec
|
data/test/autolink_test.rb
CHANGED
@@ -79,11 +79,14 @@ This is just a test. <a href="http://www.pokemon.com">http://www.pokemon.com</a>
|
|
79
79
|
pic = "http://example.com/pic.png"
|
80
80
|
url = "http://example.com/album?a&b=c"
|
81
81
|
|
82
|
-
|
82
|
+
expect = %(My pic: <a href="#{pic}"><img src="#{pic}" width="160px"></a> -- full album here #{generate_result(url)})
|
83
|
+
text = "My pic: #{pic} -- full album here #{CGI.escapeHTML url}"
|
84
|
+
|
85
|
+
assert_equal expect, Rinku.auto_link(text) { |link|
|
83
86
|
if link =~ /\.(jpg|gif|png|bmp|tif)$/i
|
84
|
-
%(<img src="#{
|
87
|
+
%(<img src="#{link}" width="160px">)
|
85
88
|
else
|
86
|
-
|
89
|
+
link
|
87
90
|
end
|
88
91
|
}
|
89
92
|
end
|
@@ -166,7 +169,7 @@ This is just a test. <a href="http://www.pokemon.com">http://www.pokemon.com</a>
|
|
166
169
|
)
|
167
170
|
|
168
171
|
urls.each do |url|
|
169
|
-
assert_linked %(<a href="#{CGI.escapeHTML
|
172
|
+
assert_linked %(<a href="#{CGI.escapeHTML url}">#{CGI.escapeHTML url}</a>), CGI.escapeHTML(url)
|
170
173
|
end
|
171
174
|
end
|
172
175
|
|
@@ -182,14 +185,14 @@ This is just a test. <a href="http://www.pokemon.com">http://www.pokemon.com</a>
|
|
182
185
|
link2_result = %{<a href="http://#{link2_raw}">#{link2_raw}</a>}
|
183
186
|
link3_raw = 'http://manuals.ruby-on-rails.com/read/chapter.need_a-period/103#page281'
|
184
187
|
link3_result = %{<a href="#{link3_raw}">#{link3_raw}</a>}
|
185
|
-
link4_raw = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor123'
|
186
|
-
link4_result = %{<a href="#{
|
188
|
+
link4_raw = CGI.escapeHTML 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor123'
|
189
|
+
link4_result = %{<a href="#{link4_raw}">#{link4_raw}</a>}
|
187
190
|
link5_raw = 'http://foo.example.com:3000/controller/action'
|
188
191
|
link5_result = %{<a href="#{link5_raw}">#{link5_raw}</a>}
|
189
192
|
link6_raw = 'http://foo.example.com:3000/controller/action+pack'
|
190
193
|
link6_result = %{<a href="#{link6_raw}">#{link6_raw}</a>}
|
191
|
-
link7_raw = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor-123'
|
192
|
-
link7_result = %{<a href="#{
|
194
|
+
link7_raw = CGI.escapeHTML 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor-123'
|
195
|
+
link7_result = %{<a href="#{link7_raw}">#{link7_raw}</a>}
|
193
196
|
link8_raw = 'http://foo.example.com:3000/controller/action.html'
|
194
197
|
link8_result = %{<a href="#{link8_raw}">#{link8_raw}</a>}
|
195
198
|
link9_raw = 'http://business.timesonline.co.uk/article/0,,9065-2473189,00.html'
|
@@ -245,7 +248,7 @@ This is just a test. <a href="http://www.pokemon.com">http://www.pokemon.com</a>
|
|
245
248
|
|
246
249
|
def generate_result(link_text, href = nil)
|
247
250
|
href ||= link_text
|
248
|
-
%{<a href="#{CGI
|
251
|
+
%{<a href="#{CGI.escapeHTML href}">#{CGI.escapeHTML link_text}</a>}
|
249
252
|
end
|
250
253
|
|
251
254
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rinku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-10 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! " A fast and very smart autolinking library that\n acts as a
|
15
15
|
drop-in replacement for Rails `auto_link`\n"
|
@@ -29,9 +29,6 @@ files:
|
|
29
29
|
- ext/rinku/buffer.c
|
30
30
|
- ext/rinku/buffer.h
|
31
31
|
- ext/rinku/extconf.rb
|
32
|
-
- ext/rinku/houdini.h
|
33
|
-
- ext/rinku/houdini_href_e.c
|
34
|
-
- ext/rinku/houdini_html_e.c
|
35
32
|
- lib/rinku.rb
|
36
33
|
- lib/rails_rinku.rb
|
37
34
|
- rinku.gemspec
|
data/ext/rinku/houdini.h
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
#ifndef __HOUDINI_H__
|
2
|
-
#define __HOUDINI_H__
|
3
|
-
|
4
|
-
#include "buffer.h"
|
5
|
-
|
6
|
-
#ifdef HOUDINI_USE_LOCALE
|
7
|
-
# define _isxdigit(c) isxdigit(c)
|
8
|
-
# define _isdigit(c) isdigit(c)
|
9
|
-
#else
|
10
|
-
/*
|
11
|
-
* Helper _isdigit methods -- do not trust the current locale
|
12
|
-
* */
|
13
|
-
# define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
|
14
|
-
# define _isdigit(c) ((c) >= '0' && (c) <= '9')
|
15
|
-
#endif
|
16
|
-
|
17
|
-
extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);
|
18
|
-
extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);
|
19
|
-
extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);
|
20
|
-
extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);
|
21
|
-
extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);
|
22
|
-
extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);
|
23
|
-
extern void houdini_unescape_uri(struct buf *ob, const uint8_t *src, size_t size);
|
24
|
-
extern void houdini_unescape_url(struct buf *ob, const uint8_t *src, size_t size);
|
25
|
-
extern void houdini_escape_js(struct buf *ob, const uint8_t *src, size_t size);
|
26
|
-
extern void houdini_unescape_js(struct buf *ob, const uint8_t *src, size_t size);
|
27
|
-
|
28
|
-
#endif
|
data/ext/rinku/houdini_href_e.c
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
#include <assert.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <string.h>
|
4
|
-
|
5
|
-
#include "houdini.h"
|
6
|
-
|
7
|
-
#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10)
|
8
|
-
|
9
|
-
/*
|
10
|
-
* The following characters will not be escaped:
|
11
|
-
*
|
12
|
-
* -_.+!*'(),%#@?=;:/,+&$ alphanum
|
13
|
-
*
|
14
|
-
* Note that this character set is the addition of:
|
15
|
-
*
|
16
|
-
* - The characters which are safe to be in an URL
|
17
|
-
* - The characters which are *not* safe to be in
|
18
|
-
* an URL because they are RESERVED characters.
|
19
|
-
*
|
20
|
-
* We asume (lazily) that any RESERVED char that
|
21
|
-
* appears inside an URL is actually meant to
|
22
|
-
* have its native function (i.e. as an URL
|
23
|
-
* component/separator) and hence needs no escaping.
|
24
|
-
*
|
25
|
-
* There are two exceptions: the chacters & (amp)
|
26
|
-
* and ' (single quote) do not appear in the table.
|
27
|
-
* They are meant to appear in the URL as components,
|
28
|
-
* yet they require special HTML-entity escaping
|
29
|
-
* to generate valid HTML markup.
|
30
|
-
*
|
31
|
-
* All other characters will be escaped to %XX.
|
32
|
-
*
|
33
|
-
*/
|
34
|
-
static const char HREF_SAFE[] = {
|
35
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
-
0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
38
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
|
39
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
40
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
|
41
|
-
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
42
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
43
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
44
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
45
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
46
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
47
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
48
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
49
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
50
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
51
|
-
};
|
52
|
-
|
53
|
-
void
|
54
|
-
houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size)
|
55
|
-
{
|
56
|
-
static const char hex_chars[] = "0123456789ABCDEF";
|
57
|
-
size_t i = 0, org;
|
58
|
-
char hex_str[3];
|
59
|
-
|
60
|
-
bufgrow(ob, ESCAPE_GROW_FACTOR(size));
|
61
|
-
hex_str[0] = '%';
|
62
|
-
|
63
|
-
while (i < size) {
|
64
|
-
org = i;
|
65
|
-
while (i < size && HREF_SAFE[src[i]] != 0)
|
66
|
-
i++;
|
67
|
-
|
68
|
-
if (i > org)
|
69
|
-
bufput(ob, src + org, i - org);
|
70
|
-
|
71
|
-
/* escaping */
|
72
|
-
if (i >= size)
|
73
|
-
break;
|
74
|
-
|
75
|
-
switch (src[i]) {
|
76
|
-
/* amp appears all the time in URLs, but needs
|
77
|
-
* HTML-entity escaping to be inside an href */
|
78
|
-
case '&':
|
79
|
-
BUFPUTSL(ob, "&");
|
80
|
-
break;
|
81
|
-
|
82
|
-
/* the single quote is a valid URL character
|
83
|
-
* according to the standard; it needs HTML
|
84
|
-
* entity escaping too */
|
85
|
-
case '\'':
|
86
|
-
BUFPUTSL(ob, "'");
|
87
|
-
break;
|
88
|
-
|
89
|
-
/* the space can be escaped to %20 or a plus
|
90
|
-
* sign. we're going with the generic escape
|
91
|
-
* for now. the plus thing is more commonly seen
|
92
|
-
* when building GET strings */
|
93
|
-
#if 0
|
94
|
-
case ' ':
|
95
|
-
bufputc(ob, '+');
|
96
|
-
break;
|
97
|
-
#endif
|
98
|
-
|
99
|
-
/* every other character goes with a %XX escaping */
|
100
|
-
default:
|
101
|
-
hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];
|
102
|
-
hex_str[2] = hex_chars[src[i] & 0xF];
|
103
|
-
bufput(ob, hex_str, 3);
|
104
|
-
}
|
105
|
-
|
106
|
-
i++;
|
107
|
-
}
|
108
|
-
}
|
data/ext/rinku/houdini_html_e.c
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
#include <assert.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <string.h>
|
4
|
-
|
5
|
-
#include "houdini.h"
|
6
|
-
|
7
|
-
#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10) /* this is very scientific, yes */
|
8
|
-
|
9
|
-
/**
|
10
|
-
* According to the OWASP rules:
|
11
|
-
*
|
12
|
-
* & --> &
|
13
|
-
* < --> <
|
14
|
-
* > --> >
|
15
|
-
* " --> "
|
16
|
-
* ' --> ' ' is not recommended
|
17
|
-
* / --> / forward slash is included as it helps end an HTML entity
|
18
|
-
*
|
19
|
-
*/
|
20
|
-
static const char HTML_ESCAPE_TABLE[] = {
|
21
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
22
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
23
|
-
0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
24
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
|
25
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
26
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
27
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
28
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
29
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
30
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
31
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
32
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
33
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
34
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
35
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
-
};
|
38
|
-
|
39
|
-
static const char *HTML_ESCAPES[] = {
|
40
|
-
"",
|
41
|
-
""",
|
42
|
-
"&",
|
43
|
-
"'",
|
44
|
-
"/",
|
45
|
-
"<",
|
46
|
-
">"
|
47
|
-
};
|
48
|
-
|
49
|
-
void
|
50
|
-
houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
|
51
|
-
{
|
52
|
-
size_t i = 0, org, esc;
|
53
|
-
|
54
|
-
bufgrow(ob, ESCAPE_GROW_FACTOR(size));
|
55
|
-
|
56
|
-
while (i < size) {
|
57
|
-
org = i;
|
58
|
-
while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
|
59
|
-
i++;
|
60
|
-
|
61
|
-
if (i > org)
|
62
|
-
bufput(ob, src + org, i - org);
|
63
|
-
|
64
|
-
/* escaping */
|
65
|
-
if (i >= size)
|
66
|
-
break;
|
67
|
-
|
68
|
-
/* The forward slash is only escaped in secure mode */
|
69
|
-
if (src[i] == '/' && !secure) {
|
70
|
-
bufputc(ob, '/');
|
71
|
-
} else {
|
72
|
-
bufputs(ob, HTML_ESCAPES[esc]);
|
73
|
-
}
|
74
|
-
|
75
|
-
i++;
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
void
|
80
|
-
houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size)
|
81
|
-
{
|
82
|
-
houdini_escape_html0(ob, src, size, 1);
|
83
|
-
}
|
84
|
-
|