Skip to content

Commit 90a23fd

Browse files
committed
[fix]definition link changed spec from before
1 parent 99cfe86 commit 90a23fd

File tree

2 files changed

+11
-72
lines changed

2 files changed

+11
-72
lines changed

flexmark/src/main/java/com/vladsch/flexmark/ast/util/Parsing.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ public static boolean isSpaceOrTab(CharSequence s, int index) {
510510
return CharPredicate.SPACE_TAB.test(SequenceUtils.safeCharAt(s, index));
511511
}
512512

513+
private static final String ESCAPABLE_CHARS = "\"#$%&'()*+,./:;<=>?@[]\\^_`{|}~-";
513514
/**
514515
* Parse angled link destination without regex catastrophic backtracking.
515516
* Replaces regex-based parsing to prevent StackOverflowError on large URLs.
@@ -528,6 +529,7 @@ public static BasedSequence parseAngledLinkDestination(@NotNull BasedSequence in
528529
int pos = startIndex + 1;
529530

530531
while (pos < input.length()) {
532+
int nextPos = pos + 1;
531533
char c = input.charAt(pos);
532534

533535
// End of angled destination
@@ -546,22 +548,24 @@ public static BasedSequence parseAngledLinkDestination(@NotNull BasedSequence in
546548
return null;
547549
}
548550
// Check lookahead for space followed by quote
549-
if (pos + 1 < input.length()) {
550-
char next = input.charAt(pos + 1);
551-
if (next == '"' || next == '\'') {
551+
if (nextPos < input.length()) {
552+
char next = input.charAt(nextPos);
553+
if (next == '"' || next == '\'' || next == '(') {
552554
return null;
553555
}
554556
}
555557
}
556558

557559
// Escape sequence handling
558560
if (c == '\\') {
559-
pos++; // Skip the backslash
560-
if (pos >= input.length()) {
561+
if (nextPos >= input.length()) {
561562
return null; // Incomplete escape at end
562563
}
563-
// The next character is consumed regardless of whether it's escapable
564-
// This matches the original regex behavior
564+
565+
char escapedChar = input.charAt(nextPos);
566+
if (ESCAPABLE_CHARS.indexOf(escapedChar) > 0) {
567+
pos++; // Skip the escaped character
568+
}
565569
}
566570

567571
pos++;

flexmark/src/main/java/com/vladsch/flexmark/parser/internal/LinkDestinationParser.java

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@ public LinkDestinationParser(boolean allowMatchedParentheses, boolean spaceInUrl
100100

101101
public BasedSequence parseLinkDestination(BasedSequence input, int startIndex) {
102102
int iMax = input.length();
103-
104-
// Handle angled link destination to prevent StackOverflowError
105-
if (startIndex < iMax && input.charAt(startIndex) == '<') {
106-
return parseAngledLinkDestination(input, startIndex);
107-
}
108-
109103
int lastMatch = startIndex;
110104

111105
int openParenCount = 0;
@@ -289,63 +283,4 @@ public static BitSet getCharSet(char charFrom, char charTo) {
289283
}
290284
return charSet;
291285
}
292-
293-
/**
294-
* Parse angled link destination without regex catastrophic backtracking.
295-
* Replaces regex-based parsing to prevent StackOverflowError on large URLs.
296-
*
297-
* @param input the input sequence
298-
* @param startIndex starting position
299-
* @return parsed result or null if no match
300-
*/
301-
private BasedSequence parseAngledLinkDestination(BasedSequence input, int startIndex) {
302-
if (startIndex >= input.length() || input.charAt(startIndex) != '<') {
303-
return null;
304-
}
305-
306-
int pos = startIndex + 1;
307-
308-
while (pos < input.length()) {
309-
char c = input.charAt(pos);
310-
311-
// End of angled destination
312-
if (c == '>') {
313-
return input.subSequence(startIndex, pos + 1);
314-
}
315-
316-
// Invalid characters
317-
if (c == '<' || c == '\0' || c == '\t' || c == '\n' || c == '\r') {
318-
return null;
319-
}
320-
321-
// Space handling
322-
if (c == ' ') {
323-
if (!spaceInUrls) {
324-
return null;
325-
}
326-
// Check lookahead for space followed by quote
327-
if (pos + 1 < input.length()) {
328-
char next = input.charAt(pos + 1);
329-
if (next == '"' || next == '\'') {
330-
return null;
331-
}
332-
}
333-
}
334-
335-
// Escape sequence handling
336-
if (c == '\\') {
337-
pos++; // Skip the backslash
338-
if (pos >= input.length()) {
339-
return null; // Incomplete escape at end
340-
}
341-
// The next character is consumed regardless of whether it's escapable
342-
// This matches the original regex behavior
343-
}
344-
345-
pos++;
346-
}
347-
348-
// No closing '>' found
349-
return null;
350-
}
351286
}

0 commit comments

Comments
 (0)