commonmarker 0.23.2 → 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.
- checksums.yaml +4 -4
- data/bin/commonmarker +2 -7
- data/commonmarker.gemspec +2 -0
- data/ext/commonmarker/cmark-gfm_version.h +2 -2
- data/ext/commonmarker/commonmarker.c +29 -44
- data/ext/commonmarker/table.c +28 -2
- data/lib/commonmarker/version.rb +1 -1
- data/lib/commonmarker.rb +1 -3
- data/test/benchmark.rb +25 -18
- metadata +23 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc6d71b6e85fb61abc438252b07369d3264982cf8fb327d96e5e8333bb23841e
|
4
|
+
data.tar.gz: 1911965561ddf20104db09c44c4e5d25f65a277a28b825bc0c03bb172779a623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59737cb433c3f4f3d53e06d3466f1f3dcd8a40e201e8b0f26be4d553f45667137e05d980100304e720d0e8fda178da3eaa9e421608cf4e53c6d159ff9261ae3e
|
7
|
+
data.tar.gz: c3088c3219da29bdb0356f46a5b7a7f2881410c825e101f7ced3964760bfcfcb5cef57e7f3ebf5bd9f686b974ad80887fc93899e616afb211dc0e648d6352cd2
|
data/bin/commonmarker
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'optparse'
|
5
|
-
require 'ostruct'
|
6
5
|
|
7
6
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
8
7
|
require 'commonmarker'
|
@@ -11,17 +10,13 @@ root = File.expand_path('..', __dir__)
|
|
11
10
|
$LOAD_PATH.unshift File.expand_path('lib', root)
|
12
11
|
|
13
12
|
def parse_options
|
14
|
-
options =
|
13
|
+
options = Struct.new(:active_extensions, :active_parse_options, :active_render_options, :output_format, :renderer)
|
14
|
+
.new([], [:DEFAULT], [:DEFAULT], :html)
|
15
15
|
extensions = CommonMarker.extensions
|
16
16
|
parse_options = CommonMarker::Config::OPTS.fetch(:parse)
|
17
17
|
render_options = CommonMarker::Config::OPTS.fetch(:render)
|
18
18
|
format_options = CommonMarker::Config::OPTS.fetch(:format)
|
19
19
|
|
20
|
-
options.active_extensions = []
|
21
|
-
options.active_parse_options = [:DEFAULT]
|
22
|
-
options.active_render_options = [:DEFAULT]
|
23
|
-
options.output_format = :html
|
24
|
-
|
25
20
|
option_parser = OptionParser.new do |opts|
|
26
21
|
opts.banner = 'Usage: commonmarker [--html-renderer] [--extension=EXTENSION]'
|
27
22
|
opts.separator ' [--to=FORMAT]'
|
data/commonmarker.gemspec
CHANGED
@@ -23,6 +23,8 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.require_paths = %w[lib ext]
|
24
24
|
s.required_ruby_version = ['>= 2.6', '< 4.0']
|
25
25
|
|
26
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
27
|
+
|
26
28
|
s.rdoc_options += ['-x', 'ext/commonmarker/cmark/.*']
|
27
29
|
|
28
30
|
s.add_development_dependency 'awesome_print'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef CMARK_GFM_VERSION_H
|
2
2
|
#define CMARK_GFM_VERSION_H
|
3
3
|
|
4
|
-
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) |
|
5
|
-
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.
|
4
|
+
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 3)
|
5
|
+
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.3"
|
6
6
|
|
7
7
|
#endif
|
@@ -115,25 +115,23 @@ static void rb_parent_removed(VALUE val) {
|
|
115
115
|
RDATA(val)->dfree = rb_free_c_struct;
|
116
116
|
}
|
117
117
|
|
118
|
-
static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions
|
118
|
+
static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions) {
|
119
119
|
int options;
|
120
|
-
int extensions_len;
|
121
120
|
VALUE rb_ext_name;
|
122
121
|
int i;
|
123
122
|
|
124
|
-
|
123
|
+
FIXNUM_P(rb_options);
|
124
|
+
options = FIX2INT(rb_options);
|
125
|
+
|
125
126
|
Check_Type(rb_extensions, T_ARRAY);
|
126
127
|
|
127
|
-
|
128
|
-
extensions_len = RARRAY_LEN(rb_extensions);
|
128
|
+
cmark_parser *parser = cmark_parser_new(options);
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
rb_ext_name = RARRAY_PTR(rb_extensions)[i];
|
130
|
+
for (i = 0; i < RARRAY_LEN(rb_extensions); ++i) {
|
131
|
+
rb_ext_name = rb_ary_entry(rb_extensions, i);
|
133
132
|
|
134
133
|
if (!SYMBOL_P(rb_ext_name)) {
|
135
134
|
cmark_parser_free(parser);
|
136
|
-
cmark_arena_reset();
|
137
135
|
rb_raise(rb_eTypeError, "extension names should be Symbols; got a %"PRIsVALUE"", rb_obj_class(rb_ext_name));
|
138
136
|
}
|
139
137
|
|
@@ -142,7 +140,6 @@ static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions, cmark
|
|
142
140
|
|
143
141
|
if (!syntax_extension) {
|
144
142
|
cmark_parser_free(parser);
|
145
|
-
cmark_arena_reset();
|
146
143
|
rb_raise(rb_eArgError, "extension %s not found", rb_id2name(SYM2ID(rb_ext_name)));
|
147
144
|
}
|
148
145
|
|
@@ -157,33 +154,28 @@ static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions, cmark
|
|
157
154
|
*
|
158
155
|
*/
|
159
156
|
static VALUE rb_markdown_to_html(VALUE self, VALUE rb_text, VALUE rb_options, VALUE rb_extensions) {
|
160
|
-
char *
|
161
|
-
int len;
|
157
|
+
char *html;
|
162
158
|
cmark_parser *parser;
|
163
159
|
cmark_node *doc;
|
164
|
-
Check_Type(rb_text, T_STRING);
|
165
|
-
Check_Type(rb_options, T_FIXNUM);
|
166
160
|
|
167
|
-
|
161
|
+
Check_Type(rb_text, T_STRING);
|
168
162
|
|
169
|
-
|
170
|
-
len = RSTRING_LEN(rb_text);
|
163
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
171
164
|
|
172
|
-
cmark_parser_feed(parser,
|
165
|
+
cmark_parser_feed(parser, StringValuePtr(rb_text), RSTRING_LEN(rb_text));
|
173
166
|
doc = cmark_parser_finish(parser);
|
167
|
+
|
174
168
|
if (doc == NULL) {
|
175
|
-
|
169
|
+
cmark_parser_free(parser);
|
176
170
|
rb_raise(rb_eNodeError, "error parsing document");
|
177
171
|
}
|
178
172
|
|
179
|
-
|
180
|
-
html = cmark_render_html_with_mem(doc, FIX2INT(rb_options), parser->syntax_extensions, default_mem);
|
181
|
-
cmark_arena_reset();
|
173
|
+
html = cmark_render_html(doc, parser->options, parser->syntax_extensions);
|
182
174
|
|
183
|
-
|
184
|
-
|
175
|
+
cmark_parser_free(parser);
|
176
|
+
cmark_node_free(doc);
|
185
177
|
|
186
|
-
return
|
178
|
+
return rb_utf8_str_new_cstr(html);
|
187
179
|
}
|
188
180
|
|
189
181
|
/*
|
@@ -191,33 +183,28 @@ static VALUE rb_markdown_to_html(VALUE self, VALUE rb_text, VALUE rb_options, VA
|
|
191
183
|
*
|
192
184
|
*/
|
193
185
|
static VALUE rb_markdown_to_xml(VALUE self, VALUE rb_text, VALUE rb_options, VALUE rb_extensions) {
|
194
|
-
char *
|
195
|
-
int len;
|
186
|
+
char *xml;
|
196
187
|
cmark_parser *parser;
|
197
188
|
cmark_node *doc;
|
198
|
-
Check_Type(rb_text, T_STRING);
|
199
|
-
Check_Type(rb_options, T_FIXNUM);
|
200
189
|
|
201
|
-
|
190
|
+
Check_Type(rb_text, T_STRING);
|
202
191
|
|
203
|
-
|
204
|
-
len = RSTRING_LEN(rb_text);
|
192
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
205
193
|
|
206
|
-
cmark_parser_feed(parser,
|
194
|
+
cmark_parser_feed(parser, StringValuePtr(rb_text), RSTRING_LEN(rb_text));
|
207
195
|
doc = cmark_parser_finish(parser);
|
196
|
+
|
208
197
|
if (doc == NULL) {
|
209
|
-
|
198
|
+
cmark_parser_free(parser);
|
210
199
|
rb_raise(rb_eNodeError, "error parsing document");
|
211
200
|
}
|
212
201
|
|
213
|
-
|
214
|
-
xml = cmark_render_xml_with_mem(doc, FIX2INT(rb_options), default_mem);
|
215
|
-
cmark_arena_reset();
|
202
|
+
xml = cmark_render_xml(doc, parser->options);
|
216
203
|
|
217
|
-
|
218
|
-
|
204
|
+
cmark_parser_free(parser);
|
205
|
+
cmark_node_free(doc);
|
219
206
|
|
220
|
-
return
|
207
|
+
return rb_utf8_str_new_cstr(xml);
|
221
208
|
}
|
222
209
|
|
223
210
|
/*
|
@@ -308,18 +295,17 @@ static VALUE rb_node_new(VALUE self, VALUE type) {
|
|
308
295
|
static VALUE rb_parse_document(VALUE self, VALUE rb_text, VALUE rb_len,
|
309
296
|
VALUE rb_options, VALUE rb_extensions) {
|
310
297
|
char *text;
|
311
|
-
int len
|
298
|
+
int len;
|
312
299
|
cmark_parser *parser;
|
313
300
|
cmark_node *doc;
|
314
301
|
Check_Type(rb_text, T_STRING);
|
315
302
|
Check_Type(rb_len, T_FIXNUM);
|
316
303
|
Check_Type(rb_options, T_FIXNUM);
|
317
304
|
|
318
|
-
parser = prepare_parser(rb_options, rb_extensions
|
305
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
319
306
|
|
320
307
|
text = (char *)RSTRING_PTR(rb_text);
|
321
308
|
len = FIX2INT(rb_len);
|
322
|
-
options = FIX2INT(rb_options);
|
323
309
|
|
324
310
|
cmark_parser_feed(parser, text, len);
|
325
311
|
doc = cmark_parser_finish(parser);
|
@@ -614,7 +600,6 @@ static VALUE rb_render_html(VALUE self, VALUE rb_options, VALUE rb_extensions) {
|
|
614
600
|
*/
|
615
601
|
static VALUE rb_render_xml(VALUE self, VALUE rb_options) {
|
616
602
|
int options;
|
617
|
-
int i;
|
618
603
|
cmark_node *node;
|
619
604
|
Check_Type(rb_options, T_FIXNUM);
|
620
605
|
|
data/ext/commonmarker/table.c
CHANGED
@@ -129,6 +129,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
129
129
|
bufsize_t cell_matched = 1, pipe_matched = 1, offset;
|
130
130
|
int expect_more_cells = 1;
|
131
131
|
int row_end_offset = 0;
|
132
|
+
int int_overflow_abort = 0;
|
132
133
|
|
133
134
|
row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
|
134
135
|
row->n_columns = 0;
|
@@ -161,6 +162,12 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
161
162
|
++cell->internal_offset;
|
162
163
|
}
|
163
164
|
|
165
|
+
// make sure we never wrap row->n_columns
|
166
|
+
// offset will != len and our exit will clean up as intended
|
167
|
+
if (row->n_columns == UINT16_MAX) {
|
168
|
+
int_overflow_abort = 1;
|
169
|
+
break;
|
170
|
+
}
|
164
171
|
row->n_columns += 1;
|
165
172
|
row->cells = cmark_llist_append(parser->mem, row->cells, cell);
|
166
173
|
}
|
@@ -194,7 +201,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
194
201
|
}
|
195
202
|
}
|
196
203
|
|
197
|
-
if (offset != len || row->n_columns == 0) {
|
204
|
+
if (offset != len || row->n_columns == 0 || int_overflow_abort) {
|
198
205
|
free_table_row(parser->mem, row);
|
199
206
|
row = NULL;
|
200
207
|
}
|
@@ -241,6 +248,11 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
241
248
|
marker_row = row_from_string(self, parser,
|
242
249
|
input + cmark_parser_get_first_nonspace(parser),
|
243
250
|
len - cmark_parser_get_first_nonspace(parser));
|
251
|
+
// assert may be optimized out, don't rely on it for security boundaries
|
252
|
+
if (!marker_row) {
|
253
|
+
return parent_container;
|
254
|
+
}
|
255
|
+
|
244
256
|
assert(marker_row);
|
245
257
|
|
246
258
|
cmark_arena_push();
|
@@ -264,6 +276,12 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
264
276
|
len - cmark_parser_get_first_nonspace(parser));
|
265
277
|
header_row = row_from_string(self, parser, (unsigned char *)parent_string,
|
266
278
|
(int)strlen(parent_string));
|
279
|
+
// row_from_string can return NULL, add additional check to ensure n_columns match
|
280
|
+
if (!marker_row || !header_row || header_row->n_columns != marker_row->n_columns) {
|
281
|
+
free_table_row(parser->mem, marker_row);
|
282
|
+
free_table_row(parser->mem, header_row);
|
283
|
+
return parent_container;
|
284
|
+
}
|
267
285
|
}
|
268
286
|
|
269
287
|
if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
|
@@ -281,8 +299,10 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
281
299
|
parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
|
282
300
|
set_n_table_columns(parent_container, header_row->n_columns);
|
283
301
|
|
302
|
+
// allocate alignments based on marker_row->n_columns
|
303
|
+
// since we populate the alignments array based on marker_row->cells
|
284
304
|
uint8_t *alignments =
|
285
|
-
(uint8_t *)parser->mem->calloc(
|
305
|
+
(uint8_t *)parser->mem->calloc(marker_row->n_columns, sizeof(uint8_t));
|
286
306
|
cmark_llist *it = marker_row->cells;
|
287
307
|
for (i = 0; it; it = it->next, ++i) {
|
288
308
|
node_cell *node = (node_cell *)it->data;
|
@@ -351,6 +371,12 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
|
|
351
371
|
row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),
|
352
372
|
len - cmark_parser_get_first_nonspace(parser));
|
353
373
|
|
374
|
+
if (!row) {
|
375
|
+
// clean up the dangling node
|
376
|
+
cmark_node_free(table_row_block);
|
377
|
+
return NULL;
|
378
|
+
}
|
379
|
+
|
354
380
|
{
|
355
381
|
cmark_llist *tmp;
|
356
382
|
int i, table_columns = get_n_table_columns(parent_container);
|
data/lib/commonmarker/version.rb
CHANGED
data/lib/commonmarker.rb
CHANGED
@@ -23,9 +23,7 @@ module CommonMarker
|
|
23
23
|
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
|
24
24
|
|
25
25
|
opts = Config.process_options(options, :render)
|
26
|
-
text
|
27
|
-
html = Node.markdown_to_html(text, opts, extensions)
|
28
|
-
html.force_encoding('UTF-8')
|
26
|
+
Node.markdown_to_html(text.encode('UTF-8'), opts, extensions)
|
29
27
|
end
|
30
28
|
|
31
29
|
# Public: Parses a Markdown string into a `document` node.
|
data/test/benchmark.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'benchmark/ips'
|
3
4
|
require 'commonmarker'
|
4
|
-
require 'github/markdown'
|
5
5
|
require 'redcarpet'
|
6
6
|
require 'kramdown'
|
7
7
|
require 'benchmark'
|
8
8
|
|
9
|
-
|
10
|
-
puts name
|
11
|
-
puts Benchmark.measure(&blk)
|
12
|
-
end
|
9
|
+
benchinput = File.read('test/benchinput.md').freeze
|
13
10
|
|
14
|
-
|
11
|
+
printf("input size = %<bytes>d bytes\n\n", { bytes: benchinput.bytesize })
|
15
12
|
|
16
|
-
|
13
|
+
Benchmark.ips do |x|
|
14
|
+
x.report('redcarpet') do
|
15
|
+
Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: false, tables: false).render(benchinput)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
18
|
+
x.report('commonmarker with to_html') do
|
19
|
+
CommonMarker.render_html(benchinput)
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
22
|
+
x.report('commonmarker with to_xml') do
|
23
|
+
CommonMarker.render_html(benchinput)
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
end
|
26
|
+
x.report('commonmarker with ruby HtmlRenderer') do
|
27
|
+
CommonMarker::HtmlRenderer.new.render(CommonMarker.render_doc(benchinput))
|
28
|
+
end
|
29
|
+
|
30
|
+
x.report('commonmarker with render_doc.to_html') do
|
31
|
+
CommonMarker.render_doc(benchinput, :DEFAULT, [:autolink]).to_html(:DEFAULT, [:autolink])
|
32
|
+
end
|
33
|
+
|
34
|
+
x.report('kramdown') do
|
35
|
+
Kramdown::Document.new(benchinput).to_html(benchinput)
|
36
|
+
end
|
29
37
|
|
30
|
-
|
31
|
-
Kramdown::Document.new(benchinput).to_html(benchinput)
|
38
|
+
x.compare!
|
32
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: commonmarker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen Torikian
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: awesome_print
|
@@ -259,7 +259,8 @@ files:
|
|
259
259
|
homepage: https://github.com/gjtorikian/commonmarker
|
260
260
|
licenses:
|
261
261
|
- MIT
|
262
|
-
metadata:
|
262
|
+
metadata:
|
263
|
+
rubygems_mfa_required: 'true'
|
263
264
|
post_install_message:
|
264
265
|
rdoc_options:
|
265
266
|
- "-x"
|
@@ -281,34 +282,34 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
282
|
- !ruby/object:Gem::Version
|
282
283
|
version: '0'
|
283
284
|
requirements: []
|
284
|
-
rubygems_version: 3.
|
285
|
+
rubygems_version: 3.3.3
|
285
286
|
signing_key:
|
286
287
|
specification_version: 4
|
287
288
|
summary: CommonMark parser and renderer. Written in C, wrapped in Ruby.
|
288
289
|
test_files:
|
290
|
+
- test/benchmark.rb
|
291
|
+
- test/fixtures/curly.md
|
292
|
+
- test/fixtures/dingus.md
|
293
|
+
- test/fixtures/strong.md
|
294
|
+
- test/fixtures/table.md
|
289
295
|
- test/test_attributes.rb
|
290
|
-
- test/
|
291
|
-
- test/test_doc.rb
|
292
|
-
- test/test_plaintext.rb
|
293
|
-
- test/test_pathological_inputs.rb
|
294
|
-
- test/test_node.rb
|
295
|
-
- test/test_maliciousness.rb
|
296
|
+
- test/test_basics.rb
|
296
297
|
- test/test_commands.rb
|
297
|
-
- test/test_tasklists.rb
|
298
298
|
- test/test_commonmark.rb
|
299
|
+
- test/test_doc.rb
|
299
300
|
- test/test_encoding.rb
|
300
|
-
- test/test_smartpunct.rb
|
301
|
-
- test/test_spec.rb
|
302
|
-
- test/test_footnotes.rb
|
303
301
|
- test/test_extensions.rb
|
304
|
-
- test/
|
305
|
-
- test/
|
306
|
-
- test/fixtures/table.md
|
307
|
-
- test/fixtures/curly.md
|
302
|
+
- test/test_footnotes.rb
|
303
|
+
- test/test_gc.rb
|
308
304
|
- test/test_helper.rb
|
305
|
+
- test/test_linebreaks.rb
|
306
|
+
- test/test_maliciousness.rb
|
307
|
+
- test/test_node.rb
|
309
308
|
- test/test_options.rb
|
310
|
-
- test/
|
311
|
-
- test/
|
312
|
-
- test/test_basics.rb
|
309
|
+
- test/test_pathological_inputs.rb
|
310
|
+
- test/test_plaintext.rb
|
313
311
|
- test/test_renderer.rb
|
314
|
-
- test/
|
312
|
+
- test/test_smartpunct.rb
|
313
|
+
- test/test_spec.rb
|
314
|
+
- test/test_tasklists.rb
|
315
|
+
- test/test_xml.rb
|