rbbcode 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +80 -14
- data/spec/html_maker_spec.rb +16 -6
- metadata +2 -2
data/README
CHANGED
@@ -4,13 +4,13 @@ RbbCode validates and cleans input. It supports customizable schemas so you can
|
|
4
4
|
|
5
5
|
Example usage:
|
6
6
|
|
7
|
-
require 'rubygems'
|
8
|
-
require 'rbbcode'
|
9
|
-
|
10
|
-
bb_code = 'This is [b]bold[/b] text'
|
11
|
-
parser = RbbCode::Parser.new
|
12
|
-
html = parser.parse(bb_code)
|
13
|
-
# => '<p>This is <strong>bold</strong> text</p>'
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rbbcode'
|
9
|
+
|
10
|
+
bb_code = 'This is [b]bold[/b] text'
|
11
|
+
parser = RbbCode::Parser.new
|
12
|
+
html = parser.parse(bb_code)
|
13
|
+
# => '<p>This is <strong>bold</strong> text</p>'
|
14
14
|
|
15
15
|
Customizing
|
16
16
|
===========
|
@@ -20,9 +20,9 @@ You can customize RbbCode by subclassing HtmlMaker and/or by passing configurati
|
|
20
20
|
HtmlMaker can be extended by adding methods like this:
|
21
21
|
|
22
22
|
class MyHtmlMaker < RbbCode::HtmlMaker
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
def html_from_TAGNAME_tag(node)
|
24
|
+
# ...
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
...where TAGNAME should be replaced with the name of the tag. The method should accept an RbbCode::TagNode and return HTML as a string. (See tree_maker.rb for the definition of RbbCode::TagNode.) Anytime the parser encounters the specified tag, it will call your method and insert the returned HTML into the output.
|
@@ -36,11 +36,77 @@ RbbCode removes invalid markup by comparing the input against a Schema object. T
|
|
36
36
|
|
37
37
|
Normally, RbbCode instantiates Schema behind the scenes, but if you want to customize it, you'll have to instantiate it yourself and pass the instance to the Parser object:
|
38
38
|
|
39
|
-
schema = RbbCode::Schema.new
|
40
|
-
schema.tag('quote').may_not_be_nested # Or whatever other configuration methods you want to call
|
41
|
-
parser = RbbCode::Parser.new(:schema => schema)
|
39
|
+
schema = RbbCode::Schema.new
|
40
|
+
schema.tag('quote').may_not_be_nested # Or whatever other configuration methods you want to call
|
41
|
+
parser = RbbCode::Parser.new(:schema => schema)
|
42
42
|
|
43
43
|
Unicode Support
|
44
44
|
===============
|
45
45
|
|
46
|
-
UTF-8 compatibility is a high priority for this project. RbbCode aims to be fully compatible with UTF-8, but not with other multibyte encodings. As of the most recent release, UTF-8 support has been tested to a limited extent. It is possible that there are some hidden gotchas. Please report any bugs you may find.
|
46
|
+
UTF-8 compatibility is a high priority for this project. RbbCode aims to be fully compatible with UTF-8, but not with other multibyte encodings. As of the most recent release, UTF-8 support has been tested to a limited extent. It is possible that there are some hidden gotchas. Please report any bugs you may find.
|
47
|
+
|
48
|
+
RbbCode does not use any Unicode-aware string classes or methods. Instead, it relies on the fact that BBCode control characters are all in the ASCII range (0x00-0x7F). Since bytes in that range are not allowed as part of multibyte characters, the parser should not mistake a single byte in a multibyte character for a control character. This approach does mean that multibyte characters will be temporarily split up in the RbbCode internals. But in theory, this should be of no consequence, because they should always be correctly reassembled in the output. Please submit a bug report if this is not the case.
|
49
|
+
|
50
|
+
BBCode Syntax
|
51
|
+
=================
|
52
|
+
|
53
|
+
As of this writing, there is no official BBCode standard. There are reference implementations, but they differ quite substantially. Wikipedia seemed like the only source with any claim to being canonical, so I followed its examples. The Wikipedia article is at:
|
54
|
+
|
55
|
+
http://en.wikipedia.org/wiki/BBCode
|
56
|
+
|
57
|
+
From that, I extracted some rules for "common" BBCode syntax. Here are the rules.
|
58
|
+
|
59
|
+
Text gets wrapped in <p> tags unless it's marked up as some other block-level element such as a list. A single line break becomes a <br/>. Two line breaks mark the end of a paragraph, thus a closing </p> and possibly an opening <p>.
|
60
|
+
|
61
|
+
Tags must be in one of the following forms:
|
62
|
+
|
63
|
+
[tagname]Text[/tagname]
|
64
|
+
[tagname=value]Text[/tagname]
|
65
|
+
|
66
|
+
As you can infer from the second example, RbbCode does not support attributes like in HTML and XML. Rather, a tag can have a single "value," which is similar to an anonymous attribute. This is how [url] and [img] tags work, for example.
|
67
|
+
|
68
|
+
RbbCode does not support all the tags listed on Wikpedia out of the box, and probably never will. However, you can easily add support for as many tags as you want.
|
69
|
+
|
70
|
+
XSS Prevention
|
71
|
+
==============
|
72
|
+
|
73
|
+
Preventing XSS is one of the top priorities for RbbCode. For tags, RbbCode uses a whitelist. However, URLs can contain JavaScript, and it is not possible to construct a URL whitelist. Therefore, when parsing tags like [url] and [img], RbbCode has to use a blacklist. If you find a vulnerability there, please submit a bug report immediately.
|
74
|
+
|
75
|
+
RbbCode sanitizes its URLs in two ways. First, it prepends "http://" to any URL that doesn't have a well-formed protocol. "javascript:" is not a well-formed protocol, because it lacks the two slashes. "javascript://" should not execute. Second, RbbCode hex-encodes various permutations of the word "JavaScript." These two precautions will *hopefully* be enough to prevent browsers executing scripts in URLs, but I can't be sure, because there are a lot of browsers out there.
|
76
|
+
|
77
|
+
Also, by enforcing valid XHTML, RbbCode should prevent users breaking your layouts with unclosed tags. Submit a bug report if it doesn't.
|
78
|
+
|
79
|
+
Bug Reports
|
80
|
+
===========
|
81
|
+
|
82
|
+
This project is maintained, but bugs sometimes take a few weeks to get fixed. If you find a bug, please take the following steps. Doing so will save me effort and thus greatly increase the chance of the bug being fixed in a timely manner.
|
83
|
+
|
84
|
+
1. Make sure it's a bug and not a feature request. See below for details.
|
85
|
+
2. Write a failing spec. This project uses RSpec. If you don't know how to use it and don't care to learn, then just create a script that produces bad output. Be sure to make it clear what you think the correct output should be. (Don't just say "the output is wrong.") Provide the *shortest* possible input that demonstrates the bug. For example, "Foo bar" is better dummy text than "Mary had a little lamb whose fleece was white as snow." Don't include extra markup that isn't necessary to trigger the bug.
|
86
|
+
3. Open an issue on Github and paste in your spec or sample script. This is preferred over sending a message.
|
87
|
+
|
88
|
+
Feature Requests vs Bugs
|
89
|
+
========================
|
90
|
+
|
91
|
+
Examples of bugs:
|
92
|
+
- Executable JavaScript appears in the output
|
93
|
+
- The output is not a valid XHTML fragment
|
94
|
+
- RbbCode fails to support common BBCode syntax, as exemplified in http://en.wikipedia.org/wiki/BBCode
|
95
|
+
- UTF-8 messes up, or the output is otherwise mangled
|
96
|
+
- Any of the specs fail
|
97
|
+
|
98
|
+
Example of feature requests:
|
99
|
+
- You want support for more tags. RbbCode lets you define your own tags. So the absence of, say, the "color" tag in the default parser is not a bug
|
100
|
+
- You want to support uncommon BBCode syntax, i.e. something you wouldn't see on http://en.wikipedia.org/wiki/BBCode
|
101
|
+
|
102
|
+
Do not open an issue for a feature request. Just send a message on Github.
|
103
|
+
|
104
|
+
Installation
|
105
|
+
============
|
106
|
+
|
107
|
+
gem install rbbcode
|
108
|
+
|
109
|
+
If that doesn't work, it's probably because RbbCode is hosted on Gemcutter, and your computer doesn't know about Gemcutter yet. To fix that:
|
110
|
+
|
111
|
+
gem install gemcutter
|
112
|
+
gem tumble
|
data/spec/html_maker_spec.rb
CHANGED
@@ -36,12 +36,12 @@ describe RbbCode::HtmlMaker do
|
|
36
36
|
|
37
37
|
it 'should not allow JavaScript in URLs' do
|
38
38
|
urls = {
|
39
|
-
'javascript:alert("
|
40
|
-
'j a v a script:alert("
|
41
|
-
' javascript:alert("
|
42
|
-
'JavaScript:alert("
|
43
|
-
"java\nscript:alert(\"
|
44
|
-
"java\rscript:alert(\"
|
39
|
+
'javascript:alert("1");' => 'http://%6A%61%76%61%73%63%72%69%70%74%3Aalert(%221%22);',
|
40
|
+
'j a v a script:alert("2");' => 'http://%6A%20%61%20%76%20%61%20%73%63%72%69%70%74%3Aalert(%222%22);',
|
41
|
+
' javascript:alert("3");' => 'http://%20%6A%61%76%61%73%63%72%69%70%74%3Aalert(%223%22);',
|
42
|
+
'JavaScript:alert("4");' => 'http://%4A%61%76%61%53%63%72%69%70%74%3Aalert(%224%22);',
|
43
|
+
"java\nscript:alert(\"5\");" => 'http://%6A%61%76%61%0A%73%63%72%69%70%74%3Aalert(%225%22);',
|
44
|
+
"java\rscript:alert(\"6\");" => 'http://%6A%61%76%61%0D%73%63%72%69%70%74%3Aalert(%226%22);'
|
45
45
|
}
|
46
46
|
|
47
47
|
# url tag
|
@@ -66,5 +66,15 @@ describe RbbCode::HtmlMaker do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
it 'should hex-encode double-quotes in the URL' do
|
71
|
+
expect_html('<p><a href="http://example.com/foo%22bar">Foo</a></p>') do
|
72
|
+
tag('p') do
|
73
|
+
tag('url', 'http://example.com/foo"bar') do
|
74
|
+
text 'Foo'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
69
79
|
end
|
70
80
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbcode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jarrett Colby
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-31 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|