Coder Social home page Coder Social logo

peg-markdown's Introduction

Note: this package is unmaintained.

What is this?

This is an implementation of John Gruber's markdown in C. It uses a parsing expression grammar (PEG) to define the syntax. This should allow easy modification and extension. It currently supports output in HTML, LaTeX, ODF, or groff_mm formats, and adding new formats is relatively easy.

It is pretty fast. A 179K text file that takes 5.7 seconds for Markdown.pl (v. 1.0.1) to parse takes less than 0.2 seconds for this markdown. It does, however, use a lot of memory (up to 4M of heap space while parsing the 179K file, and up to 80K for a 4K file). (Note that the memory leaks in earlier versions of this program have now been plugged.)

Both a library and a standalone program are provided.

peg-markdown is written and maintained by John MacFarlane (jgm on github), with significant contributions by Ryan Tomayko (rtomayko). It is released under both the GPL and the MIT license; see LICENSE for details.

Installing

On a linux or unix-based system

This program is written in portable ANSI C. It requires glib2. Most *nix systems will have this installed already. The build system requires GNU make.

The other required dependency, Ian Piumarta's peg/leg PEG parser generator, is included in the source directory. It will be built automatically. (However, it is not as portable as peg-markdown itself, and seems to require gcc.)

To make the 'markdown' executable:

make

(Or, on some systems, gmake.) Then, for usage instructions:

./markdown --help

To run John Gruber's Markdown 1.0.3 test suite:

make test

The test suite will fail on one of the list tests. Here's why. Markdown.pl encloses "item one" in the following list in <p> tags:

1.  item one
    * subitem
    * subitem

2.  item two

3.  item three

peg-markdown does not enclose "item one" in <p> tags unless it has a following blank line. This is consistent with the official markdown syntax description, and lets the author of the document choose whether <p> tags are desired.

Cross-compiling for Windows with MinGW on a linux box

Prerequisites:

Steps:

  1. Create the markdown parser using Linux-compiled leg from peg-0.1.4:

    ./peg-0.1.4/leg markdown_parser.leg >markdown_parser.c
    

    (Note: The same thing could be accomplished by cross-compiling leg, executing it on Windows, and copying the resulting C file to the Linux cross-compiler host.)

  2. Run the cross compiler with include flag for the Windows glib-2.0 headers: for example,

    /usr/bin/i586-mingw32msvc-cc -c \
    -I/usr/i586-mingw32msvc/include/glib-2.0 \
    -I/usr/i586-mingw32msvc/lib/glib-2.0/include -Wall -O3 -ansi markdown*.c
    
  3. Link against Windows glib-2.0 headers: for example,

    /usr/bin/i586-mingw32msvc-cc markdown*.o \
    -Wl,-L/usr/i586-mingw32msvc/lib/glib,--dy,--warn-unresolved-symbols,-lglib-2.0 \
    -o markdown.exe
    

The resulting executable depends on the glib dll file, so be sure to load the glib binary on the Windows host.

Compiling with MinGW on Windows

These directions assume that MinGW is installed in c:\MinGW and glib-2.0 is installed in the MinGW directory hierarchy (with the mingw bin directory in the system path).

Unzip peg-markdown in a temp directory. From the directory with the peg-markdown source, execute:

cd peg-0.1.4
make PKG_CONFIG=c:/path/to/glib/bin/pkg-config.exe

Extensions

peg-markdown supports extensions to standard markdown syntax. These can be turned on using the command line flag -x or --extensions. -x by itself turns on all extensions. Extensions can also be turned on selectively, using individual command-line options. To see the available extensions:

./markdown --help-extensions

The --smart extension provides "smart quotes", dashes, and ellipses.

The --notes extension provides a footnote syntax like that of Pandoc or PHP Markdown Extra.

The --strike extension provides a strike-through syntax like that of Redcarpet. For strike-through support in LaTeX documents the sout macro from the ulem package is used. Add \usepackage[normalem]{ulem} to your document's preamble to load it.

Using the library

The library exports two functions:

GString * markdown_to_g_string(char *text, int extensions, int output_format);
char * markdown_to_string(char *text, int extensions, int output_format);

The only difference between these is that markdown_to_g_string returns a GString (glib's automatically resizable string), while markdown_to_string returns a regular character pointer. The memory allocated for these must be freed by the calling program, using g_string_free() or free().

text is the markdown-formatted text to be converted. Note that tabs will be converted to spaces, using a four-space tab stop. Character encodings are ignored.

extensions is a bit-field specifying which syntax extensions should be used. If extensions is 0, no extensions will be used. If it is 0xFFFFFF, all extensions will be used. To set extensions selectively, use the bitwise & operator and the following constants:

  • EXT_SMART turns on smart quotes, dashes, and ellipses.
  • EXT_NOTES turns on footnote syntax. Pandoc's footnote syntax is used here.
  • EXT_FILTER_HTML filters out raw HTML (except for styles).
  • EXT_FILTER_STYLES filters out styles in HTML.
  • EXT_STRIKE turns on strike-through syntax.

output_format is either HTML_FORMAT, LATEX_FORMAT, ODF_FORMAT, or GROFF_MM_FORMAT.

To use the library, include markdown_lib.h. See markdown.c for an example.

Hacking

It should be pretty easy to modify the program to produce other formats, and to parse syntax extensions. A quick guide:

  • markdown_parser.leg contains the grammar itself.

  • markdown_output.c contains functions for printing the Element structure in various output formats.

  • To add an output format, add the format to markdown_formats in markdown_lib.h. Then modify print_element in markdown_output.c, and add functions print_XXXX_string, print_XXXX_element, and print_XXXX_element_list. Also add an option in the main program that selects the new format. Don't forget to add it to the list of formats in the usage message.

  • To add syntax extensions, define them in the PEG grammar (markdown_parser.leg), using existing extensions as a guide. New inline elements will need to be added to Inline =; new block elements will need to be added to Block =. (Note: the order of the alternatives does matter in PEG grammars.)

  • If you need to add new types of elements, modify the keys enum in markdown_peg.h.

  • By using &{ } rules one can selectively disable extensions depending on command-line options. For example, &{ extension(EXT_SMART) } succeeds only if the EXT_SMART bit of the global syntax_extensions is set. Add your option to markdown_extensions in markdown_lib.h, and add an option in markdown.c to turn on your extension.

  • Note: Avoid using [^abc] character classes in the grammar, because they cause problems with non-ascii input. Instead, use: ( !'a' !'b' !'c' . )

Acknowledgements

Support for ODF output was added by Fletcher T. Penney.

peg-markdown's People

Contributors

fletcher avatar ingydotnet avatar jgm avatar matttyson avatar rctay avatar rekado avatar rtomayko avatar zaffy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

peg-markdown's Issues

Slow parsing with inline HTML on 0.4.14

Converting a document with a certain amount of inline HTML is very slow. The original document contained way more content than just the <pre> tags, thus resulting in even higher conversion time. I stripped it down to just the inline HTML in order to ease reproduction.

I created a gist for the mentioned document.

$ peg-markdown -v
peg-markdown version 0.4.14
Copyright (c) 2008-2009 John MacFarlane.  License GPLv2+ or MIT.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ time peg-markdown document.md
[OUTPUT STRIPPED]
real    0m4.217s
user    0m4.202s
sys 0m0.009s

Suprisingly, plain old Markdown is pretty fast at converting the document:

$ time markdown document.md
[OUTPUT STRIPPED]
real    0m0.049s
user    0m0.042s
sys 0m0.006s

make error 1 on osx

Hi John,

With Mac OS X 10.6.8 (10K540), on HEAD (5e22125..), make exits with:

markdown_parser.c: In function ‘yy_SourceContents’:
markdown_parser.c:2027: warning: label ‘l166’ defined but not used
make: *** [markdown_parser.o] Error 1

On my RHEL 5.4 box, there is the same warning but it continues to build successfully.

FYI,

Isao

% gcc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~123/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)

on RHEL

$ cat /etc/redhat-release
Red Hat Enterprise Linux Client release 5.4 (Tikanga)

$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)

NULL pointer dereference in the process_raw_blocks() function

Hi,

While fuzzing peg-markdown with Honggfuzz, I found a NULL pointer dereference in the process_raw_blocks() function.

Attaching a reproducer (gzipped so GitHub accepts it): test01.md.gz

Issue can be reproduced by running:

markdown test01.md
AddressSanitizer:DEADLYSIGNAL
=================================================================
==641623==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x00000056945a bp 0x7ffeff8c0680 sp 0x7ffeff8c05b0 T0)
==641623==The signal is caused by a READ memory access.
==641623==Hint: address points to the zero page.
    #0 0x56945a in process_raw_blocks /home/fcambus/peg-markdown/markdown_lib.c:131:41
    #1 0x569616 in process_raw_blocks /home/fcambus/peg-markdown/markdown_lib.c:139:33
    #2 0x569089 in markdown_to_g_string /home/fcambus/peg-markdown/markdown_lib.c:161:14
    #3 0x5696e0 in markdown_to_string /home/fcambus/peg-markdown/markdown_lib.c:177:11
    #4 0x4c4bbc in main /home/fcambus/peg-markdown/markdown.c:180:11
    #5 0x7f71b46590b2 in __libc_start_main /build/glibc-YYA7BZ/glibc-2.31/csu/../csu/libc-start.c:308:16
    #6 0x41c43d in _start (/home/fcambus/peg-markdown/markdown+0x41c43d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/fcambus/peg-markdown/markdown_lib.c:131:41 in process_raw_blocks
==641623==ABORTING

Failure to compile on x86_64 without -fPIC

On Fedora 20 I cannot compile HEAD:

/usr/bin/ld: markdown_parser.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
markdown_parser.o: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [library] Error 1

It works fine when I add -fPIC to the CFLAGS.
This broke with commit c3564c9. Versions before that commit build fine.

Every conversion output ends with a linefeed

We are using quite distant fork of this project, but the issue originates here. Every fork in the chain retains it unquestioned, so i dare to ask at the source.

strcat(p, "\n\n");

Having every markdown_to_* retval tailed with line feed is a bug in our books. If the line is removed, 9 of 22 tests fails in various strange ways. Our use cases are quite simple and fall in the 13 passing tests, but we would like to contribute an universally working improvement. No linefeed in, no linefeed out. Is it possible? It might be an indispensable parser preprocessing hack in which case we will give up and just remove the linefeeds on our end.

Angle bracket enclosed URL in reference link fails.

Input:

[a][b]

[b]: <http://a.com>

The output href contains <>, but the original docs http://daringfireball.net/projects/markdown/syntax#link say it should work:

The link URL may, optionally, be surrounded by angle brackets

and it works on every major implementation except multi markdown.

If I could turn back time, I would not allow angle brackets like your implementation: it is better to have a single way of doing things.

But what is done is done, so until we have a markdown specification, it is better to be compatible IMHO.

Discovered with the Markdown Test Suite at karlcow/markdown-testsuite#50 . Congrats: this is the only failing test!

Ordered and unordered lists fails in `make test`

Running make test end with the following output:

cd MarkdownTest_1.0.3; \
        ./MarkdownTest.pl --script=../markdown --tidy
Amps and angle encoding ... OK
Auto links ... OK
Backslash escapes ... OK
Blockquotes with code blocks ... OK
Code Blocks ... OK
Code Spans ... OK
Hard-wrapped paragraphs with list-like lines ... OK
Horizontal rules ... OK
Inline HTML (Advanced) ... OK
Inline HTML (Simple) ... OK
Inline HTML comments ... OK
Links, inline style ... OK
Links, reference style ... OK
Links, shortcut references ... OK
Literal quotes in titles ... OK
Markdown Documentation - Basics ... OK
Markdown Documentation - Syntax ... OK
Nested blockquotes ... OK
Ordered and unordered lists ... FAILED

138c138,139
< <li>Second:

---
> <li>
> <p>Second:</p>

Strong and em together ... OK
Tabs ... OK
Tidyness ... OK


21 passed; 1 failed.
Benchmark:  1 wallclock secs ( 0.00 usr  0.04 sys +  0.42 cusr  0.26 csys =  0.72 CPU)

Running Ubuntu 10.04.2 LTS.

Using source code straight from git pull.

not parsing content in divs

Pandoc will parse the markdown within a div. But peg-markdown does not.

Note: removing example, since I can't get it to render right here.

Very long rendering time for `_a` and `*a`

The following two snippets take about 11 seconds to be rendered to HTML on my machine:

First:

_a _a _a _a _a _a _a _a _a _a _a _a _a _a aaaaa

Second:

*a *a *a *a *a *a *a *a *a *a *a *a *a *a aaaaa

I think a similar issue was solved by defining StarLine and UlLine in markdown_parser.leg.

Undefined references when using as shared library

Hey there,
I'm trying to use peg-markdown as a shared library built by this Makefile:

CC=clang
CFLAGS=-c -g -Wall

all: clog
    $(CC) obj/main.o -Llibs/peg-markdown -lpeg-markdown -o clog

clog: src/main.c peg-markdown
    $(CC) $(CFLAGS) src/main.c `pkg-config --cflags glib-2.0` -o obj/main.o

peg-markdown:
    make CC="gcc -fPIC" -C libs/peg-markdown/ library

The generation of the .so seems to work fine but when I try to compile my main program, clang just tells me it does not know how to deal with the gstring stuff:

clang obj/main.o -Llibs/peg-markdown -lpeg-markdown -o clog
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_string_new'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_slist_free'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_slist_reverse'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_string_free'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_slist_prepend'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_string_append_printf'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_string_append'
libs/peg-markdown/libpeg-markdown.so: error: undefined reference to 'g_string_insert_c'

I tried using clang 3.3 and gcc 4.8.1

bad code block hangs peg-markdown

I just made peg-markdown hang when, by mistake, I neglected to indent the initial curly brace in the following JSON code block. To reproduce, remove the two leading tabs on the line containing the first curly brace. Best regards --Isao

+begin tab-indented sample+

In this example, the bob's Memberships Collection now contains the newly created group:

    {
      "id":2,
      "username":"bob",
      "passhash":"401c30e3eb8693eb282d5a378e3edf11201933fc",
      "mobile_no":"14087591828",
      "email":"[email protected]",
      "carrier_id":"7",
      "is_verified":1,
      "is_active":1,
      "is_quiet":0,
      "quiet_start_time":0,
      "quiet_end_time":0,
      "created":1264015711,
      "updated":1264015711,
      "Memberships":{
        "2":{
          "group_id":2,
          "status":"joined",
          "is_active":1,
          "is_admin":1,
          "created":1264013960,
          "updated":1264013960,
          "name":"team_bobby",
          "description":"ricky bobby is a winner-- you on his team?",
          "is_public":0,
          "new_user_priv":"send-receive",
          "group_created":1264013960,
          "group_updated":1264013960
        },
        "4":{
          "group_id":4,
          "status":"joined",
          "is_active":1,
          "is_admin":0,
          "created":1264016105,
          "updated":1264016105,
          "name":"abcd",
          "description":"a group for you,
           if your name is in the first four letter of the alphabet",
          "is_public":1,
          "new_user_priv":"send-receive",
          "group_created":1264015827,
          "group_updated":1264015827
        },
        "5":{
          "group_id":5,
          "status":"joined",
          "is_active":1,
          "is_admin":1,
          "created":1266542158,
          "updated":1266542158,
          "name":"disabel",
          "description":"dis abel-- that jerk",
          "is_public":1,
          "new_user_priv":"send-receive",
          "group_created":1266542158,
          "group_updated":1266542158
        }
      }
    }

+end tab-indented sample+

Null dereference in print_odf_element function

Problem Description

Note: I am aware that this project is unmaintained. However, I am still opening this issue to follow CVE's guidelines for EOL software.

There is a null dereference in the print_odf_element function when the parser handles a specially crafted Markdown file. This could be used to perform a denial-of-service attack.

Here is a minimized proof-of-concept Markdown file that triggers the bug: min_null_deref_print_odf_element.md.

The output is as follows:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==761952==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000005db3b7 bp 0x000000000014 sp 0x7fffffffe030 T0)
==761952==The signal is caused by a READ memory access.
==761952==Hint: address points to the zero page.
    #0 0x5db3b7 in print_odf_element /home/sanic/peg-markdown/markdown_output.c:1072:42
    #1 0x5dac3a in print_odf_element_list /home/sanic/peg-markdown/markdown_output.c:892:9
    #2 0x5dac3a in print_odf_element /home/sanic/peg-markdown/markdown_output.c:1054:9
    #3 0x5d4c0a in print_odf_element_list /home/sanic/peg-markdown/markdown_output.c:892:9
    #4 0x5d4c0a in print_element_list /home/sanic/peg-markdown/markdown_output.c:1146:26
    #5 0x5dca53 in markdown_to_g_string /home/sanic/peg-markdown/markdown_lib.c:163:5
    #6 0x5dce84 in markdown_to_string /home/sanic/peg-markdown/markdown_lib.c:175:11
    #7 0x4c4d06 in main /home/sanic/peg-markdown/markdown.c:180:11
    #8 0x7ffff7b25082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #9 0x41c50d in _start (/home/sanic/peg-markdown/markdown+0x41c50d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/sanic/peg-markdown/markdown_output.c:1072:42 in print_odf_element
==761952==ABORTING

Reproduction Steps

  1. Compile the project using ASAN (Address Sanitizer). For example, CC=afl-clang-fast AFL_USE_ASAN=1 make.
  2. Run ./markdown --to=odf min_null_deref_print_odf_element.md (use the proof-of-concept file attached to this report).
  3. Observe the null dereference in the output.

Heap buffer overflow in the yySet function

Problem Description

Note: I am aware that this project is unmaintained. However, I am still opening this issue to follow CVE's guidelines for EOL software.

There is a heap buffer overflow in the yySet function when the parser handles a specially crafted Markdown file. In particular, there's an out-of-bounds write to the heap left redzone, which is part of the heap header metadata.

Here is a minimized proof-of-concept Markdown file that triggers the bug: min_heap_overflow.md. The output is as follows:

=================================================================
==3241393==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x611000000280 at pc 0x0000004c6a36 bp 0x7fffffffe0c0 sp 0x7fffffffe0b8
WRITE of size 8 at 0x611000000280 thread T0
    #0 0x4c6a35 in yySet /home/sanic/peg-markdown/markdown_parser.c:288:80
    #1 0x5d45a1 in yyDone /home/sanic/peg-markdown/markdown_parser.c:255:7
    #2 0x5d45a1 in yyparsefrom /home/sanic/peg-markdown/markdown_parser.c:6736:13
    #3 0x5de691 in parse_markdown /home/sanic/peg-markdown/parsing_functions.c:112:5
    #4 0x5dca1c in markdown_to_g_string /home/sanic/peg-markdown/markdown_lib.c:157:14
    #5 0x5dce84 in markdown_to_string /home/sanic/peg-markdown/markdown_lib.c:175:11
    #6 0x4c4d06 in main /home/sanic/peg-markdown/markdown.c:180:11
    #7 0x7ffff7b25082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #8 0x41c50d in _start (/home/sanic/peg-markdown/markdown+0x41c50d)

0x611000000280 is located 0 bytes to the right of 256-byte region [0x611000000180,0x611000000280)
allocated by thread T0 here:
    #0 0x494c4d in malloc (/home/sanic/peg-markdown/markdown+0x494c4d)
    #1 0x5d4164 in yyparsefrom /home/sanic/peg-markdown/markdown_parser.c:6729:31

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/sanic/peg-markdown/markdown_parser.c:288:80 in yySet
Shadow bytes around the buggy address:
  0x0c227fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c227fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c227fff8020: 00 00 00 00 00 00 00 04 fa fa fa fa fa fa fa fa
  0x0c227fff8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c227fff8040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c227fff8050:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==3241393==ABORTING

Reproduction Steps

  1. Compile the project using ASAN (Address Sanitizer). For example, CC=afl-clang-fast AFL_USE_ASAN=1 make.
  2. Run ./markdown -x min_heap_overflow.md (use the proof-of-concept file attached to this report).
  3. Observe the heap buffer overflow in the output.

Long rendering time for invalid input

This looks similar to #18

The following snippet takes a very long time (> 10 seconds on my machine) to render:

*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
*a
aaaaa

leg is no longer built

On the latest master, leg is no longer built and the build process fails.

[rekado@mango peg-markdown]$ make
CC=gcc make -C peg-0.1.9
make[1]: Entering directory `/home/rekado/dev/peg-markdown/peg-0.1.9'
gcc -g -Wall -O3 -DNDEBUG    -c -o peg.o peg.c
In file included from peg.c:48:0:
peg.peg-c: In function ‘yy_Sequence’:
peg.peg-c:791:3: warning: label ‘l77’ defined but not used [-Wunused-label]
In file included from peg.c:48:0:
peg.c: At top level:
peg.peg-c:226:16: warning: ‘yyPush’ defined but not used [-Wunused-function]
peg.peg-c:227:16: warning: ‘yyPop’ defined but not used [-Wunused-function]
peg.peg-c:228:16: warning: ‘yySet’ defined but not used [-Wunused-function]
gcc -g -Wall -O3 -DNDEBUG    -c -o tree.o tree.c
gcc -g -Wall -O3 -DNDEBUG    -c -o compile.o compile.c
gcc -g -Wall -O3 -DNDEBUG  -o peg-new peg.o tree.o compile.o
mv peg-new peg
./leg -o leg.c leg.leg
make[1]: ./leg: Command not found
make[1]: *** [leg.c] Error 127
make[1]: Leaving directory `/home/rekado/dev/peg-markdown/peg-0.1.9'
make: *** [peg-0.1.9/leg] Error 2

Build failed on macOs Sierra

OS: macOS Sierra 10.14.4
Clang: 8.0.0
Error Message:

cc -shared markdown_parser.o markdown_output.o markdown_lib.o utility_functions.o parsing_functions.o odf.o -o libpeg-markdown.so
Undefined symbols for architecture x86_64:
  "_g_slist_free", referenced from:
      _print_element_list in markdown_output.o
  "_g_slist_prepend", referenced from:
      _print_html_element in markdown_output.o
  "_g_slist_reverse", referenced from:
      _print_element_list in markdown_output.o
  "_g_string_append", referenced from:
      _markdown_to_g_string in markdown_lib.o
      _concat_string_list in utility_functions.o
      _mk_str_from_list in utility_functions.o
  "_g_string_append_printf", referenced from:
      _print_element_list in markdown_output.o
      _print_html_element in markdown_output.o
      _print_html_string in markdown_output.o
      _print_latex_element in markdown_output.o
      _print_latex_string in markdown_output.o
      _print_groff_mm_element in markdown_output.o
      _print_odf_element in markdown_output.o
      ...
  "_g_string_free", referenced from:
      _markdown_to_g_string in markdown_lib.o
      _markdown_to_string in markdown_lib.o
      _mk_str_from_list in utility_functions.o
  "_g_string_insert_c", referenced from:
      _print_html_string in markdown_output.o
      _print_latex_string in markdown_output.o
      _print_groff_mm_element in markdown_output.o
      _print_odf_element in markdown_output.o
      _markdown_to_g_string in markdown_lib.o
  "_g_string_new", referenced from:
      _markdown_to_g_string in markdown_lib.o
      _concat_string_list in utility_functions.o
      _mk_str_from_list in utility_functions.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [library] Error 1

I have tried all possible StackOverflow answers, no one works for me.

Markdown table support

Thank you for this great parser, I'm using it in QOwnNotes!

Are there any plans to support markdown tables like:

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

Or will there never be support because it's not specified in http://daringfireball.net/projects/markdown?

Indentation level is wrong

This input

- foo

    - bar

      baz

results in this output:

<ul>
<li><p>foo</p>

<ul>
<li><p>bar</p></li>
</ul>

<p>baz</p></li>
</ul>

"baz" should be in the inner list, not outer.

make parsing of emphasis embedded within lists fast by removing the Inline rule from SetextHeading1 and 2

Emphasis and strong markup within items of lists, as in input like ./PHP Markdown Extra.mdtest/Emphasis.text from Michel Fortin's MDTest package,

1.  ***test test***
2.  ___test test___
3.  *test **test***
4.  **test *test***
...

seem to present a problem for the LEG parser, which needs (on my system) around four minutes to process that file.

The parser finds -- when looking for a Block -- _Inline_s before OrderedList or BulletList. It seems it has to do a lot of scanning before it decides that input like above is an OrderedList primarily, not emphasis.

The single place where Inlines occure before the list definitions, is within Heading, i.e. SetextHeading1 and 2.

My first thought was to move Heading behind OrderedList and BulletList in the Block definition. But this would have made headings like

1. foo
====

stop working, as "1. foo" would be interpreted as an ordered list, before the parser could check whether it is part of a heading.

Therefore I introduced a new rule HeadLine and used it in SetextHeading1 and 2:

SetextHeading1 =  h:HeadLine "===" '='* Newline
        { $$ = mk_list(H1, h); }

Headline makes use of a raw Line, which stores the heading's content into a RAW block for being processed later:

HeadLine = a: StartList Sp !Endline (<(Enumerator | Bullet)> { a = cons(mk_str(yytext), a); })*
        Line { $$->key = RAW; a = cons($$, a); }

Probably present Enumerators or Bullets at the beginning of the heading are stored into strings first, as they should not go into the raw block -- the parser would interpret them as part of lists.

The raw block will be parsed as a Plain block later, which would at present introduce a newline after <h1> resp. <h2> in the HTML output, because of the value of padded. In order to get identical output I added a padded=1; behind the opening tag in markdown_output.c:

case H1: case H2: case H3: case H4: case H5: case H6:
    lev = elt->key - H1 + 1;  /* assumes H1 ... H6 are in order */
    pad(out, 2);
    g_string_append_printf(out, "<h%1d>", lev);
+   padded = 1;
    print_html_element_list(out, elt->children, obfuscate);

These changes fix the problem mentioned above, and also reduce the time needed for processing of e.g. the markdown syntax documentation by 20%.
I stumbled across this issue when testing my translation of peg-markdown into Go, which seemed to hang on certain input. When comparing with peg-markdown, I realized that the behaviour is not language related, but a property of the current grammar.

Heap use after free in the free_element_list function

Problem Description

Note: I am aware that this project is unmaintained. However, I am still opening this issue to follow CVE's guidelines for EOL software.

There is a heap use after free in the free_element_list function when the parser handles a specially crafted Markdown file. Here is a minimized proof-of-concept Markdown file that triggers the bug: min_heap_uaf.md. The output is as follows:

=================================================================
==400541==ERROR: AddressSanitizer: heap-use-after-free on address 0x6030000001a8 at pc 0x0000005de092 bp 0x7fffffffe100 sp 0x7fffffffe0f8
READ of size 8 at 0x6030000001a8 thread T0
    #0 0x5de091 in free_element_list /home/sanic/peg-markdown/parsing_functions.c:25:21
    #1 0x5ddfcb in free_element_list /home/sanic/peg-markdown/parsing_functions.c:28:13
    #2 0x5ddfcb in free_element_list /home/sanic/peg-markdown/parsing_functions.c:28:13
    #3 0x5dca5b in markdown_to_g_string /home/sanic/peg-markdown/markdown_lib.c:165:5
    #4 0x5dce84 in markdown_to_string /home/sanic/peg-markdown/markdown_lib.c:175:11
    #5 0x4c4d06 in main /home/sanic/peg-markdown/markdown.c:180:11
    #6 0x7ffff7b25082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #7 0x41c50d in _start (/home/sanic/peg-markdown/markdown+0x41c50d)

0x6030000001a8 is located 24 bytes inside of 32-byte region [0x603000000190,0x6030000001b0)
freed by thread T0 here:
    #0 0x4949cd in free (/home/sanic/peg-markdown/markdown+0x4949cd)
    #1 0x5ddfd3 in free_element_list /home/sanic/peg-markdown/parsing_functions.c:31:9

previously allocated by thread T0 here:
    #0 0x494c4d in malloc (/home/sanic/peg-markdown/markdown+0x494c4d)
    #1 0x5dd447 in mk_element /home/sanic/peg-markdown/utility_functions.c:75:23
    #2 0x5dd447 in mk_str_from_list /home/sanic/peg-markdown/utility_functions.c:99:14

SUMMARY: AddressSanitizer: heap-use-after-free /home/sanic/peg-markdown/parsing_functions.c:25:21 in free_element_list
Shadow bytes around the buggy address:
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff8000: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff8010: fd fa fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c067fff8020: 00 00 00 00 fa fa fd fd fd fd fa fa fd fd fd fd
=>0x0c067fff8030: fa fa fd fd fd[fd]fa fa 00 00 00 00 fa fa 00 00
  0x0c067fff8040: 00 00 fa fa fd fd fd fd fa fa 00 00 00 00 fa fa
  0x0c067fff8050: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00
  0x0c067fff8060: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
  0x0c067fff8070: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa
  0x0c067fff8080: fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==400541==ABORTING

Reproduction Steps

  1. Compile the project using ASAN (Address Sanitizer). For example, CC=afl-clang-fast AFL_USE_ASAN=1 make.
  2. Run ./markdown -x min_heap_uaf.md (use the proof-of-concept file attached to this report).
  3. Observe the heap use after free in the output.

PEG parser for other than markdown

Hi, I am sorry that I have to open an issue for my question.

I really like your work on markdown parsing. I am currently trying to built some parser library with one of my language and think to use Parsing expression grammar(PEG) as my parser. I recently find this repo and it seems it is not updated in the long time.

While I see your work on commonmark-hs and it seems you are not using PEG as a parser. I am quite new in this field so apologize if I'm wrong. May I ask why you are not using PEG for your commonmark-hs?

Maybe my project is not relevant to markdown or commonmark, but I just want to have second opinion on using PEG parser.

Exponential parsing

peg-markdown takes forever to process this:

***************************************[[[[[[[[[[[[[[[[[[[[-----------------]]]]]]]]]]]]]]]]]***************************

[[[[[[[[[[[[[[[[[[[[-----------------]]]]]]]]]]]]]]]]]: ::

Bold/Emphasis regression

I apologize if this is a repeat --- I thought I emailed you about this, but now cannot find that email. So perhaps I never sent it.

A while back you fixed a problem with the strong/emph parsing that could cause the program to either fail to parse or to take a long time to parse. That worked great, however it caused a regression where the following no longer parses correctly (example sent by one of my users):

The ***quick*** brown ***fox*** jumped

The problem appears to be introduced in the 2a19a38 commit, and remains in the latest commit of peg-markdown.

Thanks!

Fletcher

Stack overflow in process_raw_blocks

Problem Description

Note: I am aware that this project is unmaintained. However, I am still opening this issue to follow CVE's guidelines for EOL software.

There is a stack overflow (aka: infinite recursion) in the process_raw_blocks function when the parser handles a specially crafted Markdown file. This could be used to perform a denial-of-service attack.

Here is a minimized proof-of-concept Markdown file that triggers the bug: min_stack_overflow.md. The output is as follows:

    #210 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #211 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #212 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #213 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #214 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #215 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #216 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #217 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #218 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #219 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #220 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #221 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #222 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #223 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #224 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #225 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #226 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #227 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #228 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #229 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #230 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #231 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #232 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #233 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #234 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #235 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #236 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #237 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #238 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #239 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #240 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #241 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #242 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #243 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #244 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #245 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #246 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #247 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33
    #248 0x5dcd55 in process_raw_blocks /home/sanic/peg-markdown/markdown_lib.c:137:33

SUMMARY: AddressSanitizer: stack-overflow /home/sanic/peg-markdown/markdown_lib.c:113 in process_raw_blocks
==2808508==ABORTING

Reproduction Steps

  1. Compile the project using ASAN (Address Sanitizer). For example, CC=afl-clang-fast AFL_USE_ASAN=1 make.
  2. Run ./markdown -x min_stack_overflow.md (use the proof-of-concept file attached to this report).
  3. Observe the stack overflow in the output.

Formal Grammar Discussion

Hello JGM,

I have been learning about formal grammars (PEG and friends), and have been diving more deeply into them. I want to tackle the problem of PEG grammars for common file specifications, like CommonMark (hard), JSON (easy), XML (easy), etc., and wanted to ask about your two implementations here and in lunamark.

I see in https://talk.commonmark.org/t/commonmark-formal-grammar/46/32, you are unhappy with either of these grammars, and I was wondering if you could point me to why/where are the 'rough edges'. I know it's been a while since you've tackled the subject, but maybe you can point me in the right directions / provide background on what was particularly hard. Feel free to resurrect this if it's like 17 years from now you see the issue.

Note: I have used your Lunamark implementation and adapted it to pure Lua 5.X, but to unsatisfactory results due to the lulpeg replacement, no big deal there, just learning for now.

Build issue on ubuntu

/usr/bin/make

peg-0.1.4/leg -o markdown_parser.c markdown_parser.leg
rule 'Notes' defined but not used
rule 'NonAlphanumeric' defined but not used
rule 'References' defined but not used
cc -c `pkg-config --cflags glib-2.0` -Wall -O3 -ansi -o markdown_parser.o markdown_parser.c
markdown_parser.c: In function ‘yy_SourceContents’:
markdown_parser.c:1948:3: warning: label ‘l172’ defined but not used
markdown_parser.c: At top level:
markdown_parser.c:1507:14: warning: ‘yy_NonAlphanumeric’ defined but not used
cc `pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` -Wall -O3 -ansi -o markdown markdown_parser.o markdown_output.o markdown_lib.o markdown.c
markdown_parser.o: In function `mk_str_from_list':
markdown_parser.c:(.text+0x11946): undefined reference to `g_string_new'
markdown_parser.c:(.text+0x11968): undefined reference to `g_string_append'
markdown_parser.c:(.text+0x11a10): undefined reference to `g_string_new'
markdown_parser.c:(.text+0x11a2a): undefined reference to `g_string_append'
markdown_parser.c:(.text+0x11a61): undefined reference to `g_string_free'
markdown_output.o: In function `print_latex_string':
markdown_output.c:(.text+0x67): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x8c): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0xa4): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0xbc): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0xd4): undefined reference to `g_string_append_printf'
markdown_output.o:markdown_output.c:(.text+0xec): more undefined references to `g_string_append_printf' follow
markdown_output.o: In function `print_latex_string':
markdown_output.c:(.text+0x12b): undefined reference to `g_string_insert_c'
markdown_output.o: In function `print_html_string':
markdown_output.c:(.text+0x18a): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x1b7): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x1dc): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x1f4): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x20c): undefined reference to `g_string_append_printf'
markdown_output.o:markdown_output.c:(.text+0x253): more undefined references to `g_string_append_printf' follow
markdown_output.o: In function `print_html_string':
markdown_output.c:(.text+0x273): undefined reference to `g_string_insert_c'
markdown_output.o: In function `print_html_element':
markdown_output.c:(.text+0x2dc): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x303): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x339): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x354): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x374): undefined reference to `g_string_append_printf'
markdown_output.o:markdown_output.c:(.text+0x384): more undefined references to `g_string_append_printf' follow
markdown_output.o: In function `print_html_element':
markdown_output.c:(.text+0x4b8): undefined reference to `g_slist_prepend'
markdown_output.c:(.text+0x4ea): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x51e): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x53e): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x57e): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x5a5): undefined reference to `g_string_append_printf'
markdown_output.o:markdown_output.c:(.text+0x5e6): more undefined references to `g_string_append_printf' follow
markdown_output.o: In function `print_groff_mm_element':
markdown_output.c:(.text+0x2123): undefined reference to `g_string_insert_c'
markdown_output.c:(.text+0x2143): undefined reference to `g_string_insert_c'
markdown_output.c:(.text+0x2163): undefined reference to `g_string_insert_c'
markdown_output.c:(.text+0x217c): undefined reference to `g_string_append_printf'
markdown_output.o: In function `print_element_list':
markdown_output.c:(.text+0x228e): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x22b4): undefined reference to `g_slist_reverse'
markdown_output.c:(.text+0x22c6): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x230e): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x2335): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x2375): undefined reference to `g_string_append_printf'
markdown_output.c:(.text+0x239e): undefined reference to `g_string_append_printf'
markdown_output.o:markdown_output.c:(.text+0x23be): more undefined references to `g_string_append_printf' follow
markdown_output.o: In function `print_element_list':
markdown_output.c:(.text+0x2422): undefined reference to `g_slist_free'
markdown_lib.o: In function `markdown_to_g_string':
markdown_lib.c:(.text+0x119): undefined reference to `g_string_new'
markdown_lib.c:(.text+0x128): undefined reference to `g_string_new'
markdown_lib.c:(.text+0x191): undefined reference to `g_string_append'
markdown_lib.c:(.text+0x1f3): undefined reference to `g_string_free'
markdown_lib.c:(.text+0x2a6): undefined reference to `g_string_insert_c'
markdown_lib.c:(.text+0x2c3): undefined reference to `g_string_insert_c'
markdown_lib.c:(.text+0x2e4): undefined reference to `g_string_insert_c'
markdown_lib.o: In function `markdown_to_string':
markdown_lib.c:(.text+0x31e): undefined reference to `g_string_free'
/tmp/ccqmX6du.o: In function `main':
markdown.c:(.text+0x55): undefined reference to `g_option_context_new'
markdown.c:(.text+0x6f): undefined reference to `g_option_context_add_main_entries'
markdown.c:(.text+0x9b): undefined reference to `g_option_group_new'
markdown.c:(.text+0xad): undefined reference to `g_option_group_add_entries'
markdown.c:(.text+0xb9): undefined reference to `g_option_context_add_group'
markdown.c:(.text+0xc9): undefined reference to `g_option_context_set_description'
markdown.c:(.text+0xe7): undefined reference to `g_option_context_parse'
markdown.c:(.text+0xf7): undefined reference to `g_option_context_free'
markdown.c:(.text+0x282): undefined reference to `g_string_new'
markdown.c:(.text+0x37b): undefined reference to `g_string_free'
markdown.c:(.text+0x415): undefined reference to `g_string_insert_c'
markdown.c:(.text+0x45d): undefined reference to `g_string_insert_c'
markdown.c:(.text+0x550): undefined reference to `g_print'
collect2: ld returned 1 exit status
make: *** [markdown] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.