commonmarker 0.17.13 → 0.23.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of commonmarker might be problematic. Click here for more details.

Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +94 -18
  3. data/Rakefile +24 -5
  4. data/bin/commonmarker +107 -47
  5. data/commonmarker.gemspec +18 -15
  6. data/ext/commonmarker/autolink.c +10 -6
  7. data/ext/commonmarker/blocks.c +102 -31
  8. data/ext/commonmarker/buffer.c +0 -1
  9. data/ext/commonmarker/chunk.h +0 -1
  10. data/ext/commonmarker/cmark-gfm-core-extensions.h +29 -0
  11. data/ext/commonmarker/cmark-gfm-extension_api.h +19 -2
  12. data/ext/commonmarker/cmark-gfm.h +19 -5
  13. data/ext/commonmarker/cmark-gfm_version.h +2 -2
  14. data/ext/commonmarker/commonmark.c +33 -12
  15. data/ext/commonmarker/commonmarker.c +209 -100
  16. data/ext/commonmarker/core-extensions.c +2 -0
  17. data/ext/commonmarker/ext_scanners.c +622 -684
  18. data/ext/commonmarker/ext_scanners.h +2 -0
  19. data/ext/commonmarker/extconf.rb +3 -1
  20. data/ext/commonmarker/footnotes.c +23 -0
  21. data/ext/commonmarker/footnotes.h +2 -0
  22. data/ext/commonmarker/houdini_href_e.c +1 -1
  23. data/ext/commonmarker/html.c +46 -25
  24. data/ext/commonmarker/inlines.c +127 -30
  25. data/ext/commonmarker/iterator.h +0 -1
  26. data/ext/commonmarker/map.h +0 -1
  27. data/ext/commonmarker/node.c +17 -3
  28. data/ext/commonmarker/node.h +9 -0
  29. data/ext/commonmarker/parser.h +2 -1
  30. data/ext/commonmarker/plaintext.c +22 -0
  31. data/ext/commonmarker/render.c +18 -15
  32. data/ext/commonmarker/render.h +0 -1
  33. data/ext/commonmarker/scanners.c +779 -953
  34. data/ext/commonmarker/scanners.h +0 -2
  35. data/ext/commonmarker/strikethrough.c +4 -1
  36. data/ext/commonmarker/syntax_extension.c +10 -0
  37. data/ext/commonmarker/syntax_extension.h +2 -0
  38. data/ext/commonmarker/table.c +178 -31
  39. data/ext/commonmarker/tasklist.c +156 -0
  40. data/ext/commonmarker/tasklist.h +8 -0
  41. data/ext/commonmarker/xml.c +9 -2
  42. data/lib/commonmarker/config.rb +41 -38
  43. data/lib/commonmarker/errors.rb +12 -0
  44. data/lib/commonmarker/node/inspect.rb +15 -17
  45. data/lib/commonmarker/node.rb +14 -2
  46. data/lib/commonmarker/renderer/html_renderer.rb +45 -36
  47. data/lib/commonmarker/renderer.rb +16 -10
  48. data/lib/commonmarker/version.rb +3 -1
  49. data/lib/commonmarker.rb +8 -7
  50. data/test/benchmark.rb +26 -21
  51. data/test/fixtures/strong.md +1 -0
  52. data/test/fixtures/table.md +10 -0
  53. data/test/test_attributes.rb +5 -3
  54. data/test/test_basics.rb +19 -0
  55. data/test/test_commands.rb +72 -0
  56. data/test/test_commonmark.rb +15 -13
  57. data/test/test_doc.rb +31 -29
  58. data/test/test_encoding.rb +9 -5
  59. data/test/test_extensions.rb +66 -73
  60. data/test/test_footnotes.rb +47 -12
  61. data/test/test_gc.rb +6 -2
  62. data/test/test_helper.rb +25 -15
  63. data/test/test_linebreaks.rb +2 -0
  64. data/test/test_maliciousness.rb +189 -190
  65. data/test/test_node.rb +12 -12
  66. data/test/test_options.rb +17 -15
  67. data/test/test_pathological_inputs.rb +14 -12
  68. data/test/test_plaintext.rb +23 -21
  69. data/test/test_renderer.rb +29 -10
  70. data/test/test_smartpunct.rb +7 -2
  71. data/test/test_spec.rb +7 -4
  72. data/test/test_tasklists.rb +43 -0
  73. data/test/test_xml.rb +107 -0
  74. metadata +74 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6f11a40dfa6f3039bd560b2845c835d884f48351
4
- data.tar.gz: 1137f49d8b7e1689e8b433e57f381617f51a97df
2
+ SHA256:
3
+ metadata.gz: bc6d71b6e85fb61abc438252b07369d3264982cf8fb327d96e5e8333bb23841e
4
+ data.tar.gz: 1911965561ddf20104db09c44c4e5d25f65a277a28b825bc0c03bb172779a623
5
5
  SHA512:
6
- metadata.gz: a58dee4e21d3b6b982f92075a3a9a6e5ac636ecd4babab6208074e8ff56b42b132ea99ef1f425368db14c4081bc53a0ac8d16c756463e0249041498c65f1faee
7
- data.tar.gz: 7f5b3476d7359b9d03b5352b6660ef269f54968b76440a74c02ef2feb93b495264ae0cc1e90bde520ee12fd035ff92e094b64180b841efe6edebf01ba69083ab
6
+ metadata.gz: 59737cb433c3f4f3d53e06d3466f1f3dcd8a40e201e8b0f26be4d553f45667137e05d980100304e720d0e8fda178da3eaa9e421608cf4e53c6d159ff9261ae3e
7
+ data.tar.gz: c3088c3219da29bdb0356f46a5b7a7f2881410c825e101f7ced3964760bfcfcb5cef57e7f3ebf5bd9f686b974ad80887fc93899e616afb211dc0e648d6352cd2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CommonMarker
2
2
 
3
- [![Build Status](https://travis-ci.org/gjtorikian/commonmarker.svg)](https://travis-ci.org/gjtorikian/commonmarker) [![Gem Version](https://badge.fury.io/rb/commonmarker.svg)](http://badge.fury.io/rb/commonmarker)
3
+ ![Build Status](https://github.com/gjtorikian/commonmarker/workflows/CI/badge.svg) [![Gem Version](https://badge.fury.io/rb/commonmarker.svg)](http://badge.fury.io/rb/commonmarker)
4
4
 
5
5
  Ruby wrapper for [libcmark-gfm](https://github.com/github/cmark),
6
6
  GitHub's fork of the reference parser for CommonMark. It passes all of the C tests, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
@@ -112,10 +112,8 @@ class MyHtmlRenderer < CommonMarker::HtmlRenderer
112
112
  end
113
113
  end
114
114
 
115
- # this renderer prints directly to STDOUT, instead
116
- # of returning a string
117
115
  myrenderer = MyHtmlRenderer.new
118
- print(myrenderer.render(doc))
116
+ puts myrenderer.render(doc)
119
117
 
120
118
  # Print any warnings to STDERR
121
119
  renderer.warnings.each do |w|
@@ -132,24 +130,31 @@ CommonMarker accepts the same options that CMark does, as symbols. Note that the
132
130
  | Name | Description
133
131
  | ----------------------------- | -----------
134
132
  | `:DEFAULT` | The default parsing system.
135
- | `:FOOTNOTES` | Parse footnotes.
136
- | `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags.
133
+ | `:SOURCEPOS` | Include source position in nodes
134
+ | `:UNSAFE` | Allow raw/custom HTML and unsafe links.
135
+ | `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`.
137
136
  | `:SMART` | Use smart punctuation (curly quotes, etc.).
137
+ | `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags.
138
+ | `:FOOTNOTES` | Parse footnotes.
138
139
  | `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet))
139
- | `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`.
140
140
 
141
141
  ### Render options
142
142
 
143
- | Name | Description |
144
- | ------------------ | ----------- |
145
- | `:DEFAULT` | The default rendering system. |
146
- | `:GITHUB_PRE_LANG` | Use GitHub-style `<pre lang>` for fenced code blocks. |
147
- | `:HARDBREAKS` | Treat `\n` as hardbreaks (by adding `<br/>`). |
148
- | `:NOBREAKS` | Translate `\n` in the source to a single whitespace. |
149
- | `:SAFE` | Suppress raw HTML and unsafe links. |
150
- | `:SOURCEPOS` | Include source position in rendered HTML. |
151
- | `:TABLE_PREFER_STYLE_ATTRIBUTES` | Use `style` insted of `align` for table cells |
152
- | `:FULL_INFO_STRING` | Include full info strings of code blocks in separate attribute |
143
+ | Name | Description |
144
+ | ------------------ | ----------- |
145
+ | `:DEFAULT` | The default rendering system. |
146
+ | `:SOURCEPOS` | Include source position in rendered HTML. |
147
+ | `:HARDBREAKS` | Treat `\n` as hardbreaks (by adding `<br/>`). |
148
+ | `:UNSAFE` | Allow raw/custom HTML and unsafe links. |
149
+ | `:NOBREAKS` | Translate `\n` in the source to a single whitespace. |
150
+ | `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`. |
151
+ | `:SMART` | Use smart punctuation (curly quotes, etc.). |
152
+ | `:GITHUB_PRE_LANG` | Use GitHub-style `<pre lang>` for fenced code blocks. |
153
+ | `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags. |
154
+ | `:FOOTNOTES` | Render footnotes. |
155
+ | `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet)) |
156
+ | `:TABLE_PREFER_STYLE_ATTRIBUTES` | Use `style` insted of `align` for table cells. |
157
+ | `:FULL_INFO_STRING` | Include full info strings of code blocks in separate attribute. |
153
158
 
154
159
  ### Passing options
155
160
 
@@ -175,9 +180,80 @@ Both `render_html` and `render_doc` take an optional third argument defining the
175
180
  The available extensions are:
176
181
 
177
182
  * `:table` - This provides support for tables.
183
+ * `:tasklist` - This provides support for task list items.
178
184
  * `:strikethrough` - This provides support for strikethroughs.
179
185
  * `:autolink` - This provides support for automatically converting URLs to anchor tags.
180
- * `:tagfilter` - This strips out [several "unsafe" HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-) from being used.
186
+ * `:tagfilter` - This escapes [several "unsafe" HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-), causing them to not have any effect.
187
+
188
+ ## Output formats
189
+
190
+ Like CMark, CommonMarker can generate output in several formats: HTML, XML, plaintext, and commonmark are currently supported.
191
+
192
+ ### HTML
193
+
194
+ The default output format, HTML, will be generated when calling `to_html` or using `--to=html` on the command line.
195
+
196
+ ```ruby
197
+ doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
198
+ puts(doc.to_html)
199
+
200
+ <p><em>Hello</em> world!</p>
201
+ ```
202
+
203
+ ### XML
204
+
205
+ XML will be generated when calling `to_xml` or using `--to=xml` on the command line.
206
+
207
+ ```ruby
208
+ doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
209
+ puts(doc.to_xml)
210
+
211
+ <?xml version="1.0" encoding="UTF-8"?>
212
+ <!DOCTYPE document SYSTEM "CommonMark.dtd">
213
+ <document xmlns="http://commonmark.org/xml/1.0">
214
+ <paragraph>
215
+ <emph>
216
+ <text xml:space="preserve">Hello</text>
217
+ </emph>
218
+ <text xml:space="preserve"> world!</text>
219
+ </paragraph>
220
+ </document>
221
+ ```
222
+
223
+ ### Plaintext
224
+
225
+ Plaintext will be generated when calling `to_plaintext` or using `--to=plaintext` on the command line.
226
+
227
+ ```ruby
228
+ doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
229
+ puts(doc.to_plaintext)
230
+
231
+ Hello world!
232
+ ```
233
+
234
+ ### Commonmark
235
+
236
+ Commonmark will be generated when calling `to_commonmark` or using `--to=commonmark` on the command line.
237
+
238
+ ``` ruby
239
+ text = <<-TEXT
240
+ 1. I am a numeric list.
241
+ 2. I continue the list.
242
+ * Suddenly, an unordered list!
243
+ * What fun!
244
+ TEXT
245
+
246
+ doc = CommonMarker.render_doc(text, :DEFAULT)
247
+ puts(doc.to_commonmark)
248
+
249
+ 1. I am a numeric list.
250
+ 2. I continue the list.
251
+
252
+ <!-- end list -->
253
+
254
+ - Suddenly, an unordered list\!
255
+ - What fun\!
256
+ ```
181
257
 
182
258
  ## Developing locally
183
259
 
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'rake/clean'
3
5
  require 'rake/extensiontask'
@@ -6,7 +8,7 @@ require 'digest/md5'
6
8
  host_os = RbConfig::CONFIG['host_os']
7
9
  require 'devkit' if host_os == 'mingw32'
8
10
 
9
- task :default => [:test]
11
+ task default: [:test]
10
12
 
11
13
  # Gem Spec
12
14
  gem_spec = Gem::Specification.load('commonmarker.gemspec')
@@ -33,14 +35,18 @@ end
33
35
  task 'test:unit' => :compile
34
36
 
35
37
  desc 'Run unit and conformance tests'
36
- task :test => %w(test:unit)
38
+ task test: %w[test:unit]
39
+
40
+ require 'rubocop/rake_task'
41
+
42
+ RuboCop::RakeTask.new(:rubocop)
37
43
 
38
44
  desc 'Run benchmarks'
39
45
  task :benchmark do
40
46
  if ENV['FETCH_PROGIT']
41
47
  `rm -rf test/progit`
42
48
  `git clone https://github.com/progit/progit.git test/progit`
43
- langs = %w(ar az be ca cs de en eo es es-ni fa fi fr hi hu id it ja ko mk nl no-nb pl pt-br ro ru sr th tr uk vi zh zh-tw)
49
+ langs = %w[ar az be ca cs de en eo es es-ni fa fi fr hi hu id it ja ko mk nl no-nb pl pt-br ro ru sr th tr uk vi zh zh-tw]
44
50
  langs.each do |lang|
45
51
  `cat test/progit/#{lang}/*/*.markdown >> test/benchinput.md`
46
52
  end
@@ -70,13 +76,26 @@ RDoc::Task.new do |rd|
70
76
  rd.options << '--fileboxes'
71
77
  end
72
78
 
79
+ desc 'Generate the documentation and run a web server'
80
+ task serve: [:rdoc] do
81
+ require 'webrick'
82
+
83
+ puts 'Navigate to http://localhost:3000 to see the docs'
84
+
85
+ server = WEBrick::HTTPServer.new Port: 3000
86
+ server.mount '/', WEBrick::HTTPServlet::FileHandler, 'docs'
87
+ trap('INT') { server.stop }
88
+ server.start
89
+ end
90
+
73
91
  desc 'Generate and publish docs to gh-pages'
74
- task :publish => [:rdoc] do
92
+ task publish: [:rdoc] do
93
+ require 'tmpdir'
75
94
  require 'shellwords'
76
95
 
77
96
  Dir.mktmpdir do |tmp|
78
97
  system "mv docs/* #{tmp}"
79
- system 'git checkout gh-pages'
98
+ system 'git checkout origin/gh-pages'
80
99
  system 'rm -rf *'
81
100
  system "mv #{tmp}/* ."
82
101
  message = Shellwords.escape("Site updated at #{Time.now.utc}")
data/bin/commonmarker CHANGED
@@ -1,58 +1,118 @@
1
1
  #!/usr/bin/env ruby
2
- # Usage: commonmarker [--html-renderer] [--list-extensions] [--extension=EXTENSION] [FILE..]
3
- # Convert one or more CommonMark files to HTML and write to standard output.
4
- # If no FILE argument is provided, text will be read from STDIN.
5
- # With --html-renderer, use the HtmlRenderer renderer rather than the native C
6
- # renderer.
7
- # With --extension=EXTENSION, EXTENSION will be used for parsing, and HTML
8
- # output unless --html-renderer is specified.
9
- if ARGV.include?('--help') or ARGV.include?('-h')
10
- File.read(__FILE__).split("\n").grep(/^# /).each do |line|
11
- puts line[2..-1]
12
- end
13
- exit 0
14
- end
2
+ # frozen_string_literal: true
15
3
 
16
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
4
+ require 'optparse'
5
+
6
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
17
7
  require 'commonmarker'
18
8
 
19
- if ARGV.include?('--version') or ARGV.include?('-v')
20
- puts "commonmarker #{CommonMarker::VERSION}"
21
- exit 0
22
- end
9
+ root = File.expand_path('..', __dir__)
10
+ $LOAD_PATH.unshift File.expand_path('lib', root)
23
11
 
24
- root = File.expand_path('../../', __FILE__)
25
- $:.unshift File.expand_path('lib', root)
26
-
27
- extensions = CommonMarker.extensions
28
- active_extensions = []
29
-
30
- renderer = nil
31
- ARGV.delete_if do |arg|
32
- if arg =~ /^--html-renderer$/
33
- renderer = true
34
- true
35
- elsif arg =~ /^--list-extensions$/
36
- puts extensions
37
- exit 0
38
- elsif arg =~ /^--extension=(.+)$/
39
- if extensions.include?($1)
40
- active_extensions << $1.intern
41
- else
42
- STDERR.puts "extension #$1 not found"
43
- exit 1
12
+ def parse_options
13
+ options = Struct.new(:active_extensions, :active_parse_options, :active_render_options, :output_format, :renderer)
14
+ .new([], [:DEFAULT], [:DEFAULT], :html)
15
+ extensions = CommonMarker.extensions
16
+ parse_options = CommonMarker::Config::OPTS.fetch(:parse)
17
+ render_options = CommonMarker::Config::OPTS.fetch(:render)
18
+ format_options = CommonMarker::Config::OPTS.fetch(:format)
19
+
20
+ option_parser = OptionParser.new do |opts|
21
+ opts.banner = 'Usage: commonmarker [--html-renderer] [--extension=EXTENSION]'
22
+ opts.separator ' [--to=FORMAT]'
23
+ opts.separator ' [--parse-option=OPTION]'
24
+ opts.separator ' [--render-option=OPTION]'
25
+ opts.separator ' [FILE..]'
26
+ opts.separator ''
27
+ opts.separator 'Convert one or more CommonMark files to HTML and write to standard output.'
28
+ opts.separator 'If no FILE argument is provided, text will be read from STDIN.'
29
+ opts.separator ''
30
+
31
+ opts.on('--extension=EXTENSION', Array, 'Use EXTENSION for parsing and HTML output (unless --html-renderer is specified)') do |values|
32
+ values.each do |value|
33
+ if extensions.include?(value)
34
+ options.active_extensions << value.to_sym
35
+ else
36
+ abort("extension '#{value}' not found")
37
+ end
38
+ end
39
+ end
40
+
41
+ opts.on('-h', '--help', 'Prints this help') do
42
+ puts opts
43
+ puts
44
+ puts "Available formats: #{format_options.join(', ')}"
45
+ puts "Available extentions: #{extensions.join(', ')}"
46
+ puts "Available parse options: #{parse_options.keys.join(', ')}"
47
+ puts "Available render options: #{render_options.keys.join(', ')}"
48
+ puts
49
+ puts 'See the README for more information on these.'
50
+ exit
51
+ end
52
+
53
+ opts.on('-tFORMAT', '--to=FORMAT', String, 'Specify output FORMAT') do |value|
54
+ value = value.to_sym
55
+ if format_options.include?(value)
56
+ options.output_format = value
57
+ else
58
+ abort("format '#{value}' not found")
59
+ end
60
+ end
61
+
62
+ opts.on('--html-renderer', 'Use the HtmlRenderer renderer rather than the native C renderer (only valid when format is html)') do
63
+ options.renderer = true
64
+ end
65
+
66
+ opts.on('--parse-option=OPTION', Array, 'OPTION passed during parsing') do |values|
67
+ values.each do |value|
68
+ if parse_options.key?(value.to_sym)
69
+ options.active_parse_options << value.to_sym
70
+ else
71
+ abort("parse-option '#{value}' not found")
72
+ end
73
+ end
74
+ end
75
+
76
+ opts.on('--render-option=OPTION', Array, 'OPTION passed during rendering') do |values|
77
+ values.each do |value|
78
+ if render_options.key?(value.to_sym)
79
+ options.active_render_options << value.to_sym
80
+ else
81
+ abort("render-option '#{value}' not found")
82
+ end
83
+ end
84
+ end
85
+
86
+ opts.on('-v', '--version', 'Version information') do
87
+ puts "commonmarker #{CommonMarker::VERSION}"
88
+ exit
44
89
  end
45
- true
46
- else
47
- false
48
90
  end
91
+
92
+ option_parser.parse!
93
+
94
+ options
49
95
  end
50
96
 
51
- doc = CommonMarker.render_doc(ARGF.read, :DEFAULT, active_extensions)
97
+ options = parse_options
98
+
99
+ abort("format '#{options.output_format}' does not support using the HtmlRenderer renderer") if
100
+ options.renderer && options.output_format != :html
52
101
 
53
- if renderer
54
- renderer = CommonMarker::HtmlRenderer.new(extensions: active_extensions)
55
- STDOUT.write(renderer.render(doc))
56
- else
57
- STDOUT.write(doc.to_html(:DEFAULT, active_extensions))
102
+ doc = CommonMarker.render_doc(ARGF.read, options.active_parse_options, options.active_extensions)
103
+
104
+ case options.output_format
105
+ when :html
106
+ if options.renderer
107
+ renderer = CommonMarker::HtmlRenderer.new(options: options.active_render_options, extensions: options.active_extensions)
108
+ $stdout.write(renderer.render(doc))
109
+ else
110
+ $stdout.write(doc.to_html(options.active_render_options, options.active_extensions))
111
+ end
112
+ when :xml
113
+ $stdout.write(doc.to_xml(options.active_render_options))
114
+ when :commonmark
115
+ $stdout.write(doc.to_commonmark(options.active_render_options))
116
+ when :plaintext
117
+ $stdout.write(doc.to_plaintext(options.active_render_options))
58
118
  end
data/commonmarker.gemspec CHANGED
@@ -1,5 +1,6 @@
1
- # encoding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'commonmarker/version'
5
6
 
@@ -8,29 +9,31 @@ Gem::Specification.new do |s|
8
9
  s.version = CommonMarker::VERSION
9
10
  s.summary = 'CommonMark parser and renderer. Written in C, wrapped in Ruby.'
10
11
  s.description = 'A fast, safe, extensible parser for CommonMark. This wraps the official libcmark library.'
11
- s.authors = ['Garen Torikian', 'Ashe Connor']
12
- s.homepage = 'http://github.com/gjtorikian/commonmarker'
12
+ s.authors = ['Garen Torikian', 'Ashe Connor']
13
+ s.homepage = 'https://github.com/gjtorikian/commonmarker'
13
14
  s.license = 'MIT'
14
- s.required_ruby_version = '>= 2.0.0'
15
15
 
16
- s.files = %w(LICENSE.txt README.md Rakefile commonmarker.gemspec bin/commonmarker)
16
+ s.files = %w[LICENSE.txt README.md Rakefile commonmarker.gemspec bin/commonmarker]
17
17
  s.files += Dir.glob('lib/**/*.rb')
18
18
  s.files += Dir.glob('ext/commonmarker/*.*')
19
- s.test_files = Dir.glob('test/**/*')
19
+ s.test_files = Dir.glob('test/**/*').reject { |f| f == 'test/benchinput.md' || f.start_with?('test/progit/') }
20
20
  s.extensions = ['ext/commonmarker/extconf.rb']
21
21
 
22
- s.test_files = s.files.grep(%r{^test/})
23
22
  s.executables = ['commonmarker']
24
- s.require_paths = %w(lib ext)
23
+ s.require_paths = %w[lib ext]
24
+ s.required_ruby_version = ['>= 2.6', '< 4.0']
25
25
 
26
- s.rdoc_options += ['-x', 'ext/commonmarker/cmark/.*']
26
+ s.metadata['rubygems_mfa_required'] = 'true'
27
27
 
28
- s.add_dependency 'ruby-enum', '~> 0.5'
28
+ s.rdoc_options += ['-x', 'ext/commonmarker/cmark/.*']
29
29
 
30
+ s.add_development_dependency 'awesome_print'
31
+ s.add_development_dependency 'json', '~> 2.3'
30
32
  s.add_development_dependency 'minitest', '~> 5.6'
33
+ s.add_development_dependency 'minitest-focus', '~> 1.1'
34
+ s.add_development_dependency 'rake'
31
35
  s.add_development_dependency 'rake-compiler', '~> 0.9'
32
- s.add_development_dependency 'bundler', '~> 1.2'
33
- s.add_development_dependency 'json', '~> 1.8.1'
34
- s.add_development_dependency 'awesome_print'
35
- s.add_development_dependency 'rdoc', '~> 5.1'
36
+ s.add_development_dependency 'rdoc', '~> 6.2'
37
+ s.add_development_dependency 'rubocop'
38
+ s.add_development_dependency 'rubocop-standard'
36
39
  end
@@ -269,7 +269,11 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
269
269
  // inline was finished in inlines.c.
270
270
  }
271
271
 
272
- static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) {
272
+ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset, int depth) {
273
+ // postprocess_text can recurse very deeply if there is a very long line of
274
+ // '@' only. Stop at a reasonable depth to ensure it cannot crash.
275
+ if (depth > 1000) return;
276
+
273
277
  size_t link_end;
274
278
  uint8_t *data = text->as.literal.data,
275
279
  *at;
@@ -307,7 +311,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
307
311
  }
308
312
 
309
313
  if (rewind == 0 || ns > 0) {
310
- postprocess_text(parser, text, max_rewind + 1 + offset);
314
+ postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
311
315
  return;
312
316
  }
313
317
 
@@ -327,14 +331,14 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
327
331
 
328
332
  if (link_end < 2 || nb != 1 || np == 0 ||
329
333
  (!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
330
- postprocess_text(parser, text, max_rewind + 1 + offset);
334
+ postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
331
335
  return;
332
336
  }
333
337
 
334
338
  link_end = autolink_delim(data, link_end);
335
339
 
336
340
  if (link_end == 0) {
337
- postprocess_text(parser, text, max_rewind + 1 + offset);
341
+ postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
338
342
  return;
339
343
  }
340
344
 
@@ -369,7 +373,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
369
373
  text->as.literal.len = offset + max_rewind - rewind;
370
374
  text->as.literal.data[text->as.literal.len] = 0;
371
375
 
372
- postprocess_text(parser, post, 0);
376
+ postprocess_text(parser, post, 0, depth + 1);
373
377
  }
374
378
 
375
379
  static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {
@@ -396,7 +400,7 @@ static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser
396
400
  }
397
401
 
398
402
  if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {
399
- postprocess_text(parser, node, 0);
403
+ postprocess_text(parser, node, 0, /*depth*/0);
400
404
  }
401
405
  }
402
406