redcarpet 1.3.0 → 1.3.1

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
@@ -625,21 +625,33 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
625
625
  struct buf *link = 0;
626
626
  struct buf *title = 0;
627
627
  size_t org_work_size = rndr->work.size;
628
- int text_has_nl = 0, ret;
628
+ int text_has_nl = 0, ret = 0;
629
629
 
630
630
  /* checking whether the correct renderer exists */
631
631
  if ((is_img && !rndr->make.image) || (!is_img && !rndr->make.link))
632
- return 0;
632
+ goto cleanup;
633
633
 
634
634
  /* looking for the matching closing bracket */
635
- for (level = 1; i < size; i += 1)
636
- if (data[i] == '\n') text_has_nl = 1;
637
- else if (data[i - 1] == '\\') continue;
638
- else if (data[i] == '[') level += 1;
635
+ for (level = 1; i < size; i += 1) {
636
+ if (data[i] == '\n')
637
+ text_has_nl = 1;
638
+
639
+ else if (data[i - 1] == '\\')
640
+ continue;
641
+
642
+ else if (data[i] == '[')
643
+ level++;
644
+
639
645
  else if (data[i] == ']') {
640
- level -= 1;
641
- if (level <= 0) break; }
642
- if (i >= size) return 0;
646
+ level--;
647
+ if (level <= 0)
648
+ break;
649
+ }
650
+ }
651
+
652
+ if (i >= size)
653
+ goto cleanup;
654
+
643
655
  txt_e = i;
644
656
  i += 1;
645
657
 
@@ -652,63 +664,72 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
652
664
  if (i < size && data[i] == '(') {
653
665
  /* skipping initial whitespace */
654
666
  i += 1;
655
- while (i < size && (data[i] == ' ' || data[i] == '\t')) i += 1;
667
+
668
+ while (i < size && (data[i] == ' ' || data[i] == '\t'))
669
+ i++;
670
+
656
671
  link_b = i;
657
672
 
658
673
  /* looking for link end: ' " ) */
659
- while (i < size
660
- && data[i] != '\'' && data[i] != '"' && data[i] != ')')
661
- i += 1;
662
- if (i >= size) return 0;
674
+ while (i < size && data[i] != '\'' && data[i] != '"' && data[i] != ')')
675
+ i++;
676
+
677
+ if (i >= size) goto cleanup;
663
678
  link_e = i;
664
679
 
665
680
  /* looking for title end if present */
666
681
  if (data[i] == '\'' || data[i] == '"') {
667
- i += 1;
682
+ i++;
668
683
  title_b = i;
669
- while (i < size && data[i] != ')')
670
- i += 1;
671
- if (i >= size) return 0;
684
+
685
+ while (i < size && data[i] != ')') i++;
686
+ if (i >= size) goto cleanup;
672
687
 
673
688
  /* skipping whitespaces after title */
674
689
  title_e = i - 1;
675
- while (title_e > title_b && (data[title_e] == ' '
676
- || data[title_e] == '\t' || data[title_e] == '\n'))
677
- title_e -= 1;
690
+ while (title_e > title_b && isspace(data[title_e]))
691
+ title_e--;
678
692
 
679
693
  /* checking for closing quote presence */
680
694
  if (data[title_e] != '\'' && data[title_e] != '"') {
681
695
  title_b = title_e = 0;
682
- link_e = i; } }
696
+ link_e = i;
697
+ }
698
+ }
683
699
 
684
700
  /* remove whitespace at the end of the link */
685
- while (link_e > link_b
686
- && (data[link_e - 1] == ' ' || data[link_e - 1] == '\t'))
687
- link_e -= 1;
701
+ while (link_e > link_b && (data[link_e - 1] == ' ' || data[link_e - 1] == '\t'))
702
+ link_e--;
688
703
 
689
704
  /* remove optional angle brackets around the link */
690
- if (data[link_b] == '<') link_b += 1;
691
- if (data[link_e - 1] == '>') link_e -= 1;
705
+ if (data[link_b] == '<') link_b++;
706
+ if (data[link_e - 1] == '>') link_e--;
692
707
 
693
708
  /* building escaped link and title */
694
709
  if (link_e > link_b) {
695
710
  if (rndr->work.size < rndr->work.asize) {
696
711
  link = rndr->work.item[rndr->work.size ++];
697
- link->size = 0; }
698
- else {
712
+ link->size = 0;
713
+ } else {
699
714
  link = bufnew(WORK_UNIT);
700
- parr_push(&rndr->work, link); }
701
- bufput(link, data + link_b, link_e - link_b); }
715
+ parr_push(&rndr->work, link);
716
+ }
717
+ bufput(link, data + link_b, link_e - link_b);
718
+ }
719
+
702
720
  if (title_e > title_b) {
703
721
  if (rndr->work.size < rndr->work.asize) {
704
722
  title = rndr->work.item[rndr->work.size ++];
705
- title->size = 0; }
706
- else {
723
+ title->size = 0;
724
+ } else {
707
725
  title = bufnew(WORK_UNIT);
708
- parr_push(&rndr->work, title); }
709
- bufput(title, data + title_b, title_e - title_b);}
726
+ parr_push(&rndr->work, title);
727
+ }
728
+ bufput(title, data + title_b, title_e - title_b);
729
+ }
710
730
 
711
- i += 1; }
731
+ i++;
732
+ }
712
733
 
713
734
  /* reference style link */
714
735
  else if (i < size && data[i] == '[') {
@@ -718,8 +739,8 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
718
739
  /* looking for the id */
719
740
  i += 1;
720
741
  link_b = i;
721
- while (i < size && data[i] != ']') i += 1;
722
- if (i >= size) return 0;
742
+ while (i < size && data[i] != ']') i++;
743
+ if (i >= size) goto cleanup;
723
744
  link_e = i;
724
745
 
725
746
  /* finding the link_ref */
@@ -727,32 +748,41 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
727
748
  if (text_has_nl) {
728
749
  struct buf *b = 0;
729
750
  size_t j;
751
+
730
752
  if (rndr->work.size < rndr->work.asize) {
731
753
  b = rndr->work.item[rndr->work.size ++];
732
- b->size = 0; }
733
- else {
754
+ b->size = 0;
755
+ } else {
734
756
  b = bufnew(WORK_UNIT);
735
- parr_push(&rndr->work, b); }
736
- for (j = 1; j < txt_e; j += 1)
757
+ parr_push(&rndr->work, b);
758
+ }
759
+
760
+ for (j = 1; j < txt_e; j++) {
737
761
  if (data[j] != '\n')
738
762
  bufputc(b, data[j]);
739
763
  else if (data[j - 1] != ' ')
740
764
  bufputc(b, ' ');
765
+ }
766
+
741
767
  id.data = b->data;
742
- id.size = b->size; }
743
- else {
768
+ id.size = b->size;
769
+ } else {
744
770
  id.data = data + 1;
745
- id.size = txt_e - 1; } }
746
- else {
771
+ id.size = txt_e - 1;
772
+ }
773
+ } else {
747
774
  id.data = data + link_b;
748
- id.size = link_e - link_b; }
775
+ id.size = link_e - link_b;
776
+ }
777
+
749
778
  lr = arr_sorted_find(&rndr->refs, &id, cmp_link_ref);
750
- if (!lr) return 0;
779
+ if (!lr) goto cleanup;
751
780
 
752
781
  /* keeping link and title from link_ref */
753
782
  link = lr->link;
754
783
  title = lr->title;
755
- i += 1; }
784
+ i += 1;
785
+ }
756
786
 
757
787
  /* shortcut reference style link */
758
788
  else {
@@ -763,33 +793,40 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
763
793
  if (text_has_nl) {
764
794
  struct buf *b = 0;
765
795
  size_t j;
796
+
766
797
  if (rndr->work.size < rndr->work.asize) {
767
798
  b = rndr->work.item[rndr->work.size ++];
768
- b->size = 0; }
769
- else {
799
+ b->size = 0;
800
+ } else {
770
801
  b = bufnew(WORK_UNIT);
771
- parr_push(&rndr->work, b); }
772
- for (j = 1; j < txt_e; j += 1)
802
+ parr_push(&rndr->work, b);
803
+ }
804
+
805
+ for (j = 1; j < txt_e; j++) {
773
806
  if (data[j] != '\n')
774
807
  bufputc(b, data[j]);
775
808
  else if (data[j - 1] != ' ')
776
809
  bufputc(b, ' ');
810
+ }
811
+
777
812
  id.data = b->data;
778
- id.size = b->size; }
779
- else {
813
+ id.size = b->size;
814
+ } else {
780
815
  id.data = data + 1;
781
- id.size = txt_e - 1; }
816
+ id.size = txt_e - 1;
817
+ }
782
818
 
783
819
  /* finding the link_ref */
784
820
  lr = arr_sorted_find(&rndr->refs, &id, cmp_link_ref);
785
- if (!lr) return 0;
821
+ if (!lr) goto cleanup;
786
822
 
787
823
  /* keeping link and title from link_ref */
788
824
  link = lr->link;
789
825
  title = lr->title;
790
826
 
791
827
  /* rewinding the whitespace */
792
- i = txt_e + 1; }
828
+ i = txt_e + 1;
829
+ }
793
830
 
794
831
  /* building content: img alt is escaped, link content is parsed */
795
832
  if (txt_e > 1) {
@@ -806,7 +843,6 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
806
843
  }
807
844
 
808
845
  /* calling the relevant rendering function */
809
- ret = 0;
810
846
  if (is_img) {
811
847
  if (ob->size && ob->data[ob->size - 1] == '!')
812
848
  ob->size -= 1;
@@ -816,6 +852,7 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
816
852
  ret = rndr->make.link(ob, link, title, content, &rndr->make.render_options);
817
853
 
818
854
  /* cleanup */
855
+ cleanup:
819
856
  rndr->work.size = (int)org_work_size;
820
857
  return ret ? i : 0;
821
858
  }
@@ -1027,46 +1064,63 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
1027
1064
 
1028
1065
  work.size = i;
1029
1066
  while (work.size && data[work.size - 1] == '\n')
1030
- work.size -= 1;
1067
+ work.size--;
1068
+
1031
1069
  if (!level) {
1032
1070
  struct buf *tmp = 0;
1033
1071
  if (rndr->work.size < rndr->work.asize) {
1034
1072
  tmp = rndr->work.item[rndr->work.size ++];
1035
- tmp->size = 0; }
1036
- else {
1073
+ tmp->size = 0;
1074
+ } else {
1037
1075
  tmp = bufnew(WORK_UNIT);
1038
- parr_push(&rndr->work, tmp); }
1076
+ parr_push(&rndr->work, tmp);
1077
+ }
1078
+
1039
1079
  parse_inline(tmp, rndr, work.data, work.size);
1040
1080
  if (rndr->make.paragraph)
1041
1081
  rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
1042
- rndr->work.size -= 1; }
1043
- else {
1082
+ rndr->work.size--;
1083
+
1084
+ } else {
1044
1085
  if (work.size) {
1045
1086
  size_t beg;
1046
1087
  i = work.size;
1047
1088
  work.size -= 1;
1089
+
1048
1090
  while (work.size && data[work.size] != '\n')
1049
1091
  work.size -= 1;
1092
+
1050
1093
  beg = work.size + 1;
1051
1094
  while (work.size && data[work.size - 1] == '\n')
1052
1095
  work.size -= 1;
1096
+
1053
1097
  if (work.size) {
1054
1098
  struct buf *tmp = 0;
1099
+
1055
1100
  if (rndr->work.size < rndr->work.asize) {
1056
1101
  tmp=rndr->work.item[rndr->work.size++];
1057
- tmp->size = 0; }
1058
- else {
1102
+ tmp->size = 0;
1103
+ } else {
1059
1104
  tmp = bufnew(WORK_UNIT);
1060
- parr_push(&rndr->work, tmp); }
1105
+ parr_push(&rndr->work, tmp);
1106
+ }
1107
+
1061
1108
  parse_inline(tmp, rndr, work.data, work.size);
1109
+
1062
1110
  if (rndr->make.paragraph)
1063
1111
  rndr->make.paragraph(ob, tmp, &rndr->make.render_options);
1112
+
1064
1113
  rndr->work.size -= 1;
1065
1114
  work.data += beg;
1066
- work.size = i - beg; }
1067
- else work.size = i; }
1115
+ work.size = i - beg;
1116
+ }
1117
+ else work.size = i;
1118
+ }
1119
+
1068
1120
  if (rndr->make.header)
1069
- rndr->make.header(ob, &work, level, &rndr->make.render_options);}
1121
+ rndr->make.header(ob, &work, level, &rndr->make.render_options);
1122
+ }
1123
+
1070
1124
  return end;
1071
1125
  }
1072
1126
 
@@ -1209,7 +1263,9 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
1209
1263
  }
1210
1264
 
1211
1265
  /* render of li contents */
1212
- if (has_inside_empty) *flags |= MKD_LI_BLOCK;
1266
+ if (has_inside_empty)
1267
+ *flags |= MKD_LI_BLOCK;
1268
+
1213
1269
  if (*flags & MKD_LI_BLOCK) {
1214
1270
  /* intermediate render of block li */
1215
1271
  if (sublist && sublist < work->size) {
@@ -1688,13 +1744,13 @@ markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer) {
1688
1744
 
1689
1745
  /* sorting the reference array */
1690
1746
  if (rndr.refs.size)
1691
- qsort(rndr.refs.base, rndr.refs.size, rndr.refs.unit,
1692
- cmp_link_ref_sort);
1747
+ qsort(rndr.refs.base, rndr.refs.size, rndr.refs.unit, cmp_link_ref_sort);
1693
1748
 
1694
1749
  /* adding a final newline if not already present */
1695
- if (!text->size) return;
1696
- if (text->data[text->size - 1] != '\n'
1697
- && text->data[text->size - 1] != '\r')
1750
+ if (!text->size)
1751
+ return;
1752
+
1753
+ if (text->data[text->size - 1] != '\n' && text->data[text->size - 1] != '\r')
1698
1754
  bufputc(text, '\n');
1699
1755
 
1700
1756
  /* second pass: actual rendering */
data/lib/redcarpet.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # end
27
27
  #
28
28
  class Redcarpet
29
- VERSION = '1.3.0'
29
+ VERSION = '1.3.1'
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.3.0'
3
+ s.version = '1.3.1'
4
4
  s.summary = "Ruby bindings for libupskirt"
5
5
  s.date = '2011-04-05'
6
6
  s.email = 'vicent@github.com'
@@ -131,4 +131,19 @@ class RedcarpetTest < Test::Unit::TestCase
131
131
  def test_unbound_recursion
132
132
  Redcarpet.new(("[" * 10000) + "foo" + ("](bar)" * 10000)).to_html
133
133
  end
134
+
135
+ def test_memory_leak_when_parsing_char_links
136
+ Redcarpet.new(<<-leaks).to_html
137
+ 2. Identify the wild-type cluster and determine all clusters
138
+ containing or contained by it:
139
+
140
+ wildtype <- wildtype.cluster(h)
141
+ wildtype.mask <- logical(nclust)
142
+ wildtype.mask[c(contains(h, wildtype),
143
+ wildtype,
144
+ contained.by(h, wildtype))] <- TRUE
145
+
146
+ This could be more elegant.
147
+ leaks
148
+ end
134
149
  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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 0
10
- version: 1.3.0
9
+ - 1
10
+ version: 1.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Natacha Port\xC3\xA9"