VYPR
High severityNVD Advisory· Published Jul 14, 2015· Updated May 6, 2026

CVE-2015-5147

CVE-2015-5147

Description

Stack-based buffer overflow in the header_anchor function in the HTML renderer in Redcarpet before 3.3.2 allows attackers to cause a denial of service (crash) and possibly execute arbitrary code via unspecified vectors.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
redcarpetRubyGems
>= 3.3.0, < 3.3.23.3.2

Affected products

1

Patches

1
2cee777c1e5b

Merge branch 'vmg/header-anchor'

https://github.com/vmg/redcarpetVicent MartiJun 22, 2015via ghsa
2 files changed · +31 53
  • ext/redcarpet/html.c+31 47 modified
    @@ -264,56 +264,35 @@ rndr_linebreak(struct buf *ob, void *opaque)
     	return 1;
     }
     
    -char *header_anchor(const struct buf *buffer)
    +static void
    +rndr_header_anchor(struct buf *out, const struct buf *anchor)
     {
    -	size_t i = 0, j, k, size = buffer->size;
    -
    -	char text[size];
    -	strcpy(text, bufcstr(buffer));
    -
    -	char raw_string[size];
    +	static const char *STRIPPED = " -&+$,/:;=?@\"#{}|^~[]`\\*()%.!'";
     
    -	/* Strip down the inline HTML markup if needed */
    -	if (strchr(text, '<') < strchr(text, '>')) {
    -		char* part = strtok(text, "<>");
    -
    -		/* Once every two times, the yielded token is the
    -		   content of a HTML tag so we don't need to copy it */
    -		for (k = 0; part != NULL; k++) {
    -			if (k == 0)
    -				strcpy(raw_string, part);
    -			else if (k % 2 == 0)
    -				strcat(raw_string, part);
    +	const uint8_t *a = anchor->data;
    +	const size_t size = anchor->size;
    +	size_t i = 0;
    +	int stripped = 0, inserted = 0;
     
    -			part = strtok(NULL, "<>");
    +	for (; i < size; ++i) {
    +		if (a[i] == '<') {
    +			while (i < size && a[i] != '>')
    +				i++;
    +		}
    +		else if (strchr(STRIPPED, a[i])) {
    +			if (inserted && !stripped)
    +				bufputc(out, '-');
    +			stripped = 1;
    +		}
    +		else {
    +			bufputc(out, tolower(a[i]));
    +			stripped = 0;
    +			inserted++;
     		}
    -
    -		size = strlen(raw_string);
    -	} else {
    -		strcpy(raw_string, text);
    -	}
    -
    -	char* heading = malloc(size * sizeof(char));
    -
    -	/* Remove leading stripped chars */
    -	while (STRIPPED_CHAR(raw_string[i])) i++;
    -
    -	/* Dasherize the string removing extra white spaces
    -	   and stripped chars */
    -	for (j = 0; i < size; i++, j++) {
    -		while ((i+1) < size && STRIPPED_CHAR(raw_string[i]) && STRIPPED_CHAR(raw_string[i+1]))
    -			i++;
    -
    -		if (STRIPPED_CHAR(raw_string[i]) && i == size - 1)
    -			break;
    -		else if (STRIPPED_CHAR(raw_string[i]))
    -			heading[j] = '-';
    -		else
    -			heading[j] = tolower(raw_string[i]);
     	}
     
    -	heading[j++] = '\0';
    -	return heading;
    +	if (stripped)
    +		out->size--;
     }
     
     static void
    @@ -324,8 +303,11 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque)
     	if (ob->size)
     		bufputc(ob, '\n');
     
    -	if ((options->flags & HTML_TOC) && (level <= options->toc_data.nesting_level))
    -		bufprintf(ob, "<h%d id=\"%s\">", level, header_anchor(text));
    +	if ((options->flags & HTML_TOC) && (level <= options->toc_data.nesting_level)) {
    +		bufprintf(ob, "<h%d id=\"", level);
    +		rndr_header_anchor(ob, text);
    +		BUFPUTSL(ob, "\">");
    +	}
     	else
     		bufprintf(ob, "<h%d>", level);
     
    @@ -694,7 +676,9 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
     			BUFPUTSL(ob,"</li>\n<li>\n");
     		}
     
    -		bufprintf(ob, "<a href=\"#%s\">", header_anchor(text));
    +		bufprintf(ob, "<a href=\"#");
    +		rndr_header_anchor(ob, text);
    +		BUFPUTSL(ob, "\">");
     
     		if (text) {
     			if (options->flags & HTML_ESCAPE)
    
  • ext/redcarpet/html.h+0 6 modified
    @@ -70,12 +70,6 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
     extern void
     sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size);
     
    -/* header method used internally in Redcarpet */
    -char *header_anchor(const struct buf *buffer);
    -
    -#define STRIPPED_CHARS " -&+$,/:;=?@\"#{}|^~[]`\\*()%.!'"
    -#define STRIPPED_CHAR(x) (strchr(STRIPPED_CHARS, x) != NULL)
    -
     #ifdef __cplusplus
     }
     #endif
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.