-
Notifications
You must be signed in to change notification settings - Fork 320
Closed
Description
I'm getting an NPE while parsing a simple document like:
foo {} is a "test" right?
The NPE seems to be caused by having two InlineParser extensions fire on the same paragraph of text. In this case I have an InlineParser extension on { and ". Code for the extensions is below. The NPE seems to be caused by the InlineParserImpl incorrectly creating the Node its passing into the second extension that fires on the paragraph. The node is not attached to any other node, it has no parent. Its not a member of the paragraph.
java.lang.NullPointerException
at org.commonmark.node.Node.insertAfter(Node.java:89)
at com.google.gitiles.doc.SmartQuotedExtension.quote(SmartQuotedExtension.java:51)
at com.google.gitiles.doc.SmartQuotedExtension.access$0(SmartQuotedExtension.java:43)
at com.google.gitiles.doc.SmartQuotedExtension$QuotedProcessor.process(SmartQuotedExtension.java:86)
at org.commonmark.internal.InlineParserImpl.processDelimiters(InlineParserImpl.java:854)
at org.commonmark.internal.InlineParserImpl.parse(InlineParserImpl.java:169)
at org.commonmark.internal.ParagraphParser.parseInlines(ParagraphParser.java:61)
at org.commonmark.internal.DocumentParser.processInlines(DocumentParser.java:410)
at org.commonmark.internal.DocumentParser.finalizeAndProcess(DocumentParser.java:529)
at org.commonmark.internal.DocumentParser.parse(DocumentParser.java:118)
at org.commonmark.parser.Parser.parse(Parser.java:60)
public class NamedAnchorExtension implements ParserExtension {
@Override
public void extend(Parser.Builder builder) {
builder.customDelimiterProcessor(new Processor());
}
private static class Processor implements DelimiterProcessor {
@Override
public char getOpeningCharacter() {
return '{';
}
@Override
public char getClosingCharacter() {
return '}';
}
@Override
public int getMinLength() {
return 1;
}
@Override
public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
return 1;
}
@Override
public void process(Text opener, Text closer, int delimiterUse) {
// Silly yes, but simplified for this issue report.
opener.insertAfter(new Text("{"));
closer.insertBefore(new Text("}"));
}
}
public class SmartQuotedExtension implements ParserExtension {
SmartQuotedExtension() {}
@Override
public void extend(Parser.Builder builder) {
builder.customDelimiterProcessor(new QuotedProcessor(SINGLE, '\''));
builder.customDelimiterProcessor(new QuotedProcessor(DOUBLE, '"'));
}
private static void quote(Type type, Text opener, Text closer) {
SmartQuoted quote = new SmartQuoted();
quote.setType(type);
for (Node t = opener.getNext(); t != null && t != closer; ) {
Node next = t.getNext();
quote.appendChild(t);
t = next;
}
opener.insertAfter(quote);
}
/** Parses single and double quoted strings for smart quotes. */
private static class QuotedProcessor implements DelimiterProcessor {
private final SmartQuoted.Type type;
private final char delim;
QuotedProcessor(SmartQuoted.Type type, char open) {
this.type = type;
this.delim = open;
}
@Override
public char getOpeningCharacter() {
return delim;
}
@Override
public char getClosingCharacter() {
return delim;
}
@Override
public int getMinLength() {
return 1;
}
@Override
public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
return 1;
}
@Override
public void process(Text opener, Text closer, int delimiterUse) {
quote(type, opener, closer);
}
}
}
public class SmartQuoted extends CustomNode {
public enum Type {
DOUBLE,
SINGLE;
}
private Type type;
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
}Metadata
Metadata
Assignees
Labels
No labels