redcarpet 1.2.1 → 1.2.2

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

Potentially problematic release.


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

data/ext/markdown.c CHANGED
@@ -47,7 +47,7 @@ struct link_ref {
47
47
  /* offset is the number of valid chars before data */
48
48
  struct render;
49
49
  typedef size_t
50
- (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
50
+ (*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth);
51
51
 
52
52
 
53
53
  /* render • structure containing one particular render */
@@ -233,17 +233,20 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink)
233
233
 
234
234
  /* parse_inline • parses inline markdown elements */
235
235
  static void
236
- parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
236
+ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
237
237
  {
238
238
  size_t i = 0, end = 0;
239
239
  char_trigger action = 0;
240
240
  struct buf work = { 0, 0, 0, 0, 0 };
241
241
 
242
+ if (depth >= rndr->make.parser_options.recursion_depth)
243
+ return;
244
+
242
245
  while (i < size) {
243
246
  /* copying inactive chars into the output */
244
- while (end < size
245
- && (action = rndr->active_char[(unsigned char)data[end]]) == 0)
246
- end += 1;
247
+ while (end < size && (action = rndr->active_char[(unsigned char)data[end]]) == 0)
248
+ end++;
249
+
247
250
  if (rndr->make.normal_text) {
248
251
  work.data = data + i;
249
252
  work.size = end - i;
@@ -251,16 +254,19 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
251
254
  }
252
255
  else
253
256
  bufput(ob, data + i, end - i);
257
+
254
258
  if (end >= size) break;
255
259
  i = end;
256
260
 
257
261
  /* calling the trigger */
258
- end = action(ob, rndr, data + i, i, size - i);
262
+ end = action(ob, rndr, data + i, i, size - i, depth + 1);
259
263
  if (!end) /* no action from the callback */
260
264
  end = i + 1;
261
265
  else {
262
266
  i += end;
263
- end = i; } }
267
+ end = i;
268
+ }
269
+ }
264
270
  }
265
271
 
266
272
  /* find_emph_char • looks for the next emph char, skipping other constructs */
@@ -317,7 +323,7 @@ find_emph_char(char *data, size_t size, char c)
317
323
  /* parse_emph1 • parsing single emphase */
318
324
  /* closed by a symbol not preceded by whitespace and not followed by symbol */
319
325
  static size_t
320
- parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
326
+ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
321
327
  {
322
328
  size_t i = 0, len;
323
329
  struct buf *work = 0;
@@ -354,7 +360,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
354
360
  parr_push(&rndr->work, work);
355
361
  }
356
362
 
357
- parse_inline(work, rndr, data, i);
363
+ parse_inline(work, rndr, data, i, depth + 1);
358
364
  r = rndr->make.emphasis(ob, work, c, &rndr->make.render_options);
359
365
  rndr->work.size -= 1;
360
366
  return r ? i + 1 : 0;
@@ -366,7 +372,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
366
372
 
367
373
  /* parse_emph2 • parsing single emphase */
368
374
  static size_t
369
- parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
375
+ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
370
376
  {
371
377
  size_t i = 0, len;
372
378
  struct buf *work = 0;
@@ -378,28 +384,30 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
378
384
  len = find_emph_char(data + i, size - i, c);
379
385
  if (!len) return 0;
380
386
  i += len;
381
- if (i + 1 < size && data[i] == c && data[i + 1] == c
382
- && i && data[i - 1] != ' '
383
- && data[i - 1] != '\t' && data[i - 1] != '\n') {
387
+
388
+ if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !isspace(data[i - 1])) {
384
389
  if (rndr->work.size < rndr->work.asize) {
385
390
  work = rndr->work.item[rndr->work.size ++];
386
- work->size = 0; }
387
- else {
391
+ work->size = 0;
392
+ } else {
388
393
  work = bufnew(WORK_UNIT);
389
- parr_push(&rndr->work, work); }
390
- parse_inline(work, rndr, data, i);
391
- r = rndr->make.double_emphasis(ob, work, c,
392
- &rndr->make.render_options);
394
+ parr_push(&rndr->work, work);
395
+ }
396
+
397
+ parse_inline(work, rndr, data, i, depth + 1);
398
+ r = rndr->make.double_emphasis(ob, work, c, &rndr->make.render_options);
393
399
  rndr->work.size -= 1;
394
- return r ? i + 2 : 0; }
395
- i += 1; }
400
+ return r ? i + 2 : 0;
401
+ }
402
+ i++;
403
+ }
396
404
  return 0;
397
405
  }
398
406
 
399
407
  /* parse_emph3 • parsing single emphase */
400
408
  /* finds the first closing tag, and delegates to the other emph */
401
409
  static size_t
402
- parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
410
+ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c, int depth)
403
411
  {
404
412
  size_t i = 0, len;
405
413
  int r;
@@ -410,67 +418,77 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
410
418
  i += len;
411
419
 
412
420
  /* skip whitespace preceded symbols */
413
- if (data[i] != c || data[i - 1] == ' '
414
- || data[i - 1] == '\t' || data[i - 1] == '\n')
421
+ if (data[i] != c || isspace(data[i - 1]))
415
422
  continue;
416
423
 
417
- if (i + 2 < size && data[i + 1] == c && data[i + 2] == c
418
- && rndr->make.triple_emphasis) {
424
+ if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->make.triple_emphasis) {
419
425
  /* triple symbol found */
420
426
  struct buf *work = 0;
421
427
  if (rndr->work.size < rndr->work.asize) {
422
428
  work = rndr->work.item[rndr->work.size ++];
423
- work->size = 0; }
424
- else {
429
+ work->size = 0;
430
+ } else {
425
431
  work = bufnew(WORK_UNIT);
426
- parr_push(&rndr->work, work); }
427
- parse_inline(work, rndr, data, i);
428
- r = rndr->make.triple_emphasis(ob, work, c,
429
- &rndr->make.render_options);
432
+ parr_push(&rndr->work, work);
433
+ }
434
+
435
+ parse_inline(work, rndr, data, i, depth + 1);
436
+ r = rndr->make.triple_emphasis(ob, work, c, &rndr->make.render_options);
430
437
  rndr->work.size -= 1;
431
- return r ? i + 3 : 0; }
432
- else if (i + 1 < size && data[i + 1] == c) {
438
+ return r ? i + 3 : 0;
439
+
440
+ } else if (i + 1 < size && data[i + 1] == c) {
433
441
  /* double symbol found, handing over to emph1 */
434
- len = parse_emph1(ob, rndr, data - 2, size + 2, c);
442
+ len = parse_emph1(ob, rndr, data - 2, size + 2, c, depth + 1);
435
443
  if (!len) return 0;
436
- else return len - 2; }
437
- else {
444
+ else return len - 2;
445
+
446
+ } else {
438
447
  /* single symbol found, handing over to emph2 */
439
- len = parse_emph2(ob, rndr, data - 1, size + 1, c);
448
+ len = parse_emph2(ob, rndr, data - 1, size + 1, c, depth + 1);
440
449
  if (!len) return 0;
441
- else return len - 1; } }
450
+ else return len - 1;
451
+ }
452
+ }
442
453
  return 0;
443
454
  }
444
455
 
445
456
  /* char_emphasis • single and double emphasis parsing */
446
457
  static size_t
447
- char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
458
+ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
448
459
  {
449
460
  char c = data[0];
450
461
  size_t ret;
462
+
451
463
  if (size > 2 && data[1] != c) {
452
464
  /* whitespace cannot follow an opening emphasis */
453
- if (data[1] == ' ' || data[1] == '\t' || data[1] == '\n'
454
- || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
465
+ if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c, depth + 1)) == 0)
455
466
  return 0;
456
- return ret + 1; }
467
+
468
+ return ret + 1;
469
+ }
470
+
457
471
  if (size > 3 && data[1] == c && data[2] != c) {
458
- if (data[2] == ' ' || data[2] == '\t' || data[2] == '\n'
459
- || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0)
472
+ if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c, depth + 1)) == 0)
460
473
  return 0;
461
- return ret + 2; }
474
+
475
+ return ret + 2;
476
+ }
477
+
462
478
  if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
463
- if (data[3] == ' ' || data[3] == '\t' || data[3] == '\n'
464
- || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
479
+ if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c, depth + 1)) == 0)
465
480
  return 0;
466
- return ret + 3; }
481
+
482
+ return ret + 3;
483
+ }
484
+
467
485
  return 0;
468
486
  }
469
487
 
470
488
 
471
489
  /* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */
472
490
  static size_t
473
- char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
491
+ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
474
492
  {
475
493
  if (offset < 2 || data[-1] != ' ' || data[-2] != ' ')
476
494
  return 0;
@@ -485,98 +503,113 @@ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, s
485
503
 
486
504
  /* char_codespan • '`' parsing a code span (assuming codespan != 0) */
487
505
  static size_t
488
- char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
506
+ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
489
507
  {
490
508
  size_t end, nb = 0, i, f_begin, f_end;
491
509
 
492
510
  /* counting the number of backticks in the delimiter */
493
- while (nb < size && data[nb] == '`') nb += 1;
511
+ while (nb < size && data[nb] == '`')
512
+ nb++;
494
513
 
495
514
  /* finding the next delimiter */
496
515
  i = 0;
497
- for (end = nb; end < size && i < nb; end += 1)
498
- if (data[end] == '`') i += 1;
516
+ for (end = nb; end < size && i < nb; end++) {
517
+ if (data[end] == '`') i++;
499
518
  else i = 0;
500
- if (i < nb && end >= size) return 0; /* no matching delimiter */
519
+ }
520
+
521
+ if (i < nb && end >= size)
522
+ return 0; /* no matching delimiter */
501
523
 
502
524
  /* trimming outside whitespaces */
503
525
  f_begin = nb;
504
526
  while (f_begin < end && (data[f_begin] == ' ' || data[f_begin] == '\t'))
505
- f_begin += 1;
527
+ f_begin++;
528
+
506
529
  f_end = end - nb;
507
530
  while (f_end > nb && (data[f_end-1] == ' ' || data[f_end-1] == '\t'))
508
- f_end -= 1;
531
+ f_end--;
509
532
 
510
533
  /* real code span */
511
534
  if (f_begin < f_end) {
512
535
  struct buf work = { data + f_begin, f_end - f_begin, 0, 0, 0 };
513
536
  if (!rndr->make.codespan(ob, &work, &rndr->make.render_options))
514
- end = 0; }
515
- else {
537
+ end = 0;
538
+ } else {
516
539
  if (!rndr->make.codespan(ob, 0, &rndr->make.render_options))
517
- end = 0; }
540
+ end = 0;
541
+ }
542
+
518
543
  return end;
519
544
  }
520
545
 
521
546
 
522
547
  /* char_escape • '\\' backslash escape */
523
548
  static size_t
524
- char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
549
+ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
525
550
  {
526
551
  struct buf work = { 0, 0, 0, 0, 0 };
552
+
527
553
  if (size > 1) {
528
554
  if (rndr->make.normal_text) {
529
555
  work.data = data + 1;
530
556
  work.size = 1;
531
- rndr->make.normal_text(ob, &work, &rndr->make.render_options); }
532
- else bufputc(ob, data[1]); }
557
+ rndr->make.normal_text(ob, &work, &rndr->make.render_options);
558
+ }
559
+ else bufputc(ob, data[1]);
560
+ }
561
+
533
562
  return 2;
534
563
  }
535
564
 
536
565
  /* char_entity • '&' escaped when it doesn't belong to an entity */
537
566
  /* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
538
567
  static size_t
539
- char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
568
+ char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
540
569
  {
541
570
  size_t end = 1;
542
571
  struct buf work;
543
- if (end < size && data[end] == '#') end += 1;
544
- while (end < size
545
- && ((data[end] >= '0' && data[end] <= '9')
546
- || (data[end] >= 'a' && data[end] <= 'z')
547
- || (data[end] >= 'A' && data[end] <= 'Z')))
548
- end += 1;
549
- if (end < size && data[end] == ';') {
550
- /* real entity */
551
- end += 1; }
552
- else {
553
- /* lone '&' */
554
- return 0; }
572
+
573
+ if (end < size && data[end] == '#')
574
+ end++;
575
+
576
+ while (end < size && isalnum(data[end]))
577
+ end++;
578
+
579
+ if (end < size && data[end] == ';')
580
+ end += 1; /* real entity */
581
+ else
582
+ return 0; /* lone '&' */
583
+
555
584
  if (rndr->make.entity) {
556
585
  work.data = data;
557
586
  work.size = end;
558
- rndr->make.entity(ob, &work, &rndr->make.render_options); }
587
+ rndr->make.entity(ob, &work, &rndr->make.render_options);
588
+ }
559
589
  else bufput(ob, data, end);
590
+
560
591
  return end;
561
592
  }
562
593
 
563
594
  /* char_langle_tag • '<' when tags or autolinks are allowed */
564
595
  static size_t
565
- char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
596
+ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
566
597
  {
567
598
  enum mkd_autolink altype = MKDA_NOT_AUTOLINK;
568
599
  size_t end = tag_length(data, size, &altype);
569
600
  struct buf work = { data, end, 0, 0, 0 };
570
601
  int ret = 0;
602
+
571
603
  if (end) {
572
604
  if (rndr->make.autolink && altype != MKDA_NOT_AUTOLINK) {
573
605
  work.data = data + 1;
574
606
  work.size = end - 2;
575
- ret = rndr->make.autolink(ob, &work, altype,
576
- &rndr->make.render_options); }
607
+ ret = rndr->make.autolink(ob, &work, altype, &rndr->make.render_options);
608
+ }
577
609
  else if (rndr->make.raw_html_tag)
578
- ret = rndr->make.raw_html_tag(ob, &work,
579
- &rndr->make.render_options); }
610
+ ret = rndr->make.raw_html_tag(ob, &work, &rndr->make.render_options);
611
+ }
612
+
580
613
  if (!ret) return 0;
581
614
  else return end;
582
615
  }
@@ -584,7 +617,7 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset,
584
617
 
585
618
  /* char_link • '[': parsing a link or an image */
586
619
  static size_t
587
- char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
620
+ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size, int depth)
588
621
  {
589
622
  int is_img = (offset && data[-1] == '!'), level;
590
623
  size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;
@@ -612,9 +645,8 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
612
645
 
613
646
  /* skip any amount of whitespace or newline */
614
647
  /* (this is much more laxist than original markdown syntax) */
615
- while (i < size
616
- && (data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))
617
- i += 1;
648
+ while (i < size && isspace(data[i]))
649
+ i++;
618
650
 
619
651
  /* inline style link */
620
652
  if (i < size && data[i] == '(') {
@@ -763,20 +795,25 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
763
795
  if (txt_e > 1) {
764
796
  if (rndr->work.size < rndr->work.asize) {
765
797
  content = rndr->work.item[rndr->work.size ++];
766
- content->size = 0; }
767
- else {
798
+ content->size = 0;
799
+ } else {
768
800
  content = bufnew(WORK_UNIT);
769
- parr_push(&rndr->work, content); }
801
+ parr_push(&rndr->work, content);
802
+ }
803
+
770
804
  if (is_img) bufput(content, data + 1, txt_e - 1);
771
- else parse_inline(content, rndr, data + 1, txt_e - 1); }
805
+ else parse_inline(content, rndr, data + 1, txt_e - 1, depth + 1);
806
+ }
772
807
 
773
808
  /* calling the relevant rendering function */
774
809
  ret = 0;
775
810
  if (is_img) {
776
- if (ob->size && ob->data[ob->size - 1] == '!') ob->size -= 1;
777
- ret = rndr->make.image(ob, link, title, content,
778
- &rndr->make.render_options); }
779
- else ret = rndr->make.link(ob, link, title, content, &rndr->make.render_options);
811
+ if (ob->size && ob->data[ob->size - 1] == '!')
812
+ ob->size -= 1;
813
+
814
+ ret = rndr->make.image(ob, link, title, content, &rndr->make.render_options);
815
+ } else
816
+ ret = rndr->make.link(ob, link, title, content, &rndr->make.render_options);
780
817
 
781
818
  /* cleanup */
782
819
  rndr->work.size = (int)org_work_size;
@@ -958,7 +995,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
958
995
 
959
996
  /* parse_blockquote • hanldes parsing of a regular paragraph */
960
997
  static size_t
961
- parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
998
+ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size, int depth)
962
999
  {
963
1000
  size_t i = 0, end = 0;
964
1001
  int level = 0;
@@ -1000,7 +1037,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1000
1037
  else {
1001
1038
  tmp = bufnew(WORK_UNIT);
1002
1039
  parr_push(&rndr->work, tmp); }
1003
- parse_inline(tmp, rndr, work.data, work.size);
1040
+ parse_inline(tmp, rndr, work.data, work.size, depth + 1);
1004
1041
  if (rndr->make.paragraph)
1005
1042
  rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
1006
1043
  rndr->work.size -= 1; }
@@ -1022,7 +1059,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1022
1059
  else {
1023
1060
  tmp = bufnew(WORK_UNIT);
1024
1061
  parr_push(&rndr->work, tmp); }
1025
- parse_inline(tmp, rndr, work.data, work.size);
1062
+ parse_inline(tmp, rndr, work.data, work.size, depth + 1);
1026
1063
  if (rndr->make.paragraph)
1027
1064
  rndr->make.paragraph(ob, tmp,
1028
1065
  &rndr->make.render_options);
@@ -1186,11 +1223,11 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
1186
1223
  } else {
1187
1224
  /* intermediate render of inline li */
1188
1225
  if (sublist && sublist < work->size) {
1189
- parse_inline(inter, rndr, work->data, sublist);
1226
+ parse_inline(inter, rndr, work->data, sublist, depth + 1);
1190
1227
  parse_block(inter, rndr, work->data + sublist, work->size - sublist, depth + 1);
1191
1228
  }
1192
1229
  else
1193
- parse_inline(inter, rndr, work->data, work->size);
1230
+ parse_inline(inter, rndr, work->data, work->size, depth + 1);
1194
1231
  }
1195
1232
 
1196
1233
  /* render of li itself */
@@ -1435,7 +1472,7 @@ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size, int de
1435
1472
  else if (prefix_oli(txt_data, end))
1436
1473
  beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED, depth + 1);
1437
1474
  else
1438
- beg += parse_paragraph(ob, rndr, txt_data, end);
1475
+ beg += parse_paragraph(ob, rndr, txt_data, end, depth + 1);
1439
1476
  }
1440
1477
  }
1441
1478
 
data/ext/redcarpet.c CHANGED
@@ -70,7 +70,8 @@ static VALUE rb_redcarpet__render(VALUE self, RendererType render_type)
70
70
  input_buf.data = RSTRING_PTR(text);
71
71
  input_buf.size = RSTRING_LEN(text);
72
72
 
73
- output_buf = bufnew(64);
73
+ output_buf = bufnew(128);
74
+ bufgrow(output_buf, RSTRING_LEN(text) * 1.2f);
74
75
 
75
76
  switch (render_type) {
76
77
  case REDCARPET_RENDER_XHTML:
data/lib/redcarpet.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # end
27
27
  #
28
28
  class Redcarpet
29
- VERSION = '1.2.1'
29
+ VERSION = '1.2.2'
30
30
 
31
31
  # Original Markdown formatted text.
32
32
  attr_reader :text
data/redcarpet.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'redcarpet'
3
- s.version = '1.2.1'
3
+ s.version = '1.2.2'
4
4
  s.summary = "Ruby bindings for libupskirt"
5
5
  s.date = '2011-04-04'
6
6
  s.email = 'vicent@github.com'
@@ -128,4 +128,7 @@ class RedcarpetTest < Test::Unit::TestCase
128
128
  assert_equal exp, rd.to_html.strip
129
129
  end
130
130
 
131
+ def test_unbound_recursion
132
+ Redcarpet.new(("[" * 10000) + "foo" + ("](bar)" * 10000)).to_html
133
+ end
131
134
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redcarpet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 1
10
- version: 1.2.1
9
+ - 2
10
+ version: 1.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Natacha Port\xC3\xA9"