Skip to content

Commit 0f2739f

Browse files
committed
issue doxygen#11273 Using a tilde in the URL of a Markdown image tag breaks the tag if the image is in the IMAGE_PATH
Adding possibility to use a `~` in the file / directory name except on the first position of a file / directory name
1 parent fd2d902 commit 0f2739f

File tree

5 files changed

+98
-32
lines changed

5 files changed

+98
-32
lines changed

src/commentscan.l

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,8 @@ ATTR ({B}+[^>\n]*)?
600600
DOCNL "\n"|"\\ilinebr"
601601
LC "\\"{B}*"\n"
602602
NW [^a-z_A-Z0-9]
603-
FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=@&#]
604-
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=@&#]
603+
FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=@&#~]
604+
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=@&#~]
605605
FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]*"\"")
606606
ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*
607607
LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
@@ -1464,6 +1464,8 @@ STopt [^\n@\\]*
14641464
BEGIN( Comment );
14651465
}
14661466
<ClassDocArg2>{FILE}|"<>" { // second argument; include file
1467+
if (yytext[0] == '~') REJECT;
1468+
if (yytext[0] == '"' && yytext[1] == '~') REJECT;
14671469
yyextra->current->includeFile = yytext;
14681470
BEGIN( ClassDocArg3 );
14691471
}
@@ -1475,6 +1477,8 @@ STopt [^\n@\\]*
14751477
}
14761478
14771479
<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
1480+
if (yytext[0] == '~') REJECT;
1481+
if ((yytext[0] == '<' || yytext[0] == '"') && yytext[1] == '~') REJECT;
14781482
yyextra->current->includeName = yytext;
14791483
BEGIN( Comment );
14801484
}
@@ -1569,6 +1573,9 @@ STopt [^\n@\\]*
15691573
QCString text = yytext;
15701574
int start = text.find('{');
15711575
int end = text.find('}',start+1);
1576+
QCString tmp = text.mid(end+2);
1577+
tmp = stripQuotes(tmp.data());
1578+
if (tmp[0] == '~') REJECT;
15721579
yyextra->current->name = text.mid(end+2);
15731580
int istart = yyextra->current->name.find("\\ilinebr");
15741581
if (istart != -1)
@@ -1582,7 +1589,9 @@ STopt [^\n@\\]*
15821589
BEGIN( PageDocArg2 );
15831590
}
15841591
<PageDocArg1>{FILE} { // first argument; page name
1585-
yyextra->current->name = stripQuotes(yytext);
1592+
QCString tmp = stripQuotes(yytext);
1593+
if (tmp[0] == '~') REJECT;
1594+
yyextra->current->name = tmp;
15861595
yyextra->current->args = "";
15871596
BEGIN( PageDocArg2 );
15881597
}
@@ -1648,7 +1657,9 @@ STopt [^\n@\\]*
16481657
BEGIN( Comment );
16491658
}
16501659
<FileDocArg1>{FILE} { // first argument; name
1651-
yyextra->current->name = stripQuotes(yytext);
1660+
QCString tmp = stripQuotes(yytext);
1661+
if (tmp[0] == '~') REJECT;
1662+
yyextra->current->name = tmp;
16521663
BEGIN( Comment );
16531664
}
16541665
<FileDocArg1>{LC} { yyextra->lineNr++;
@@ -1846,10 +1857,10 @@ STopt [^\n@\\]*
18461857
/* ----- handle arguments of the ifile command ----- */
18471858
18481859
<IFile,IFileSection>{FILE} {
1860+
QCString tmp = stripQuotes(yytext);
1861+
if (tmp[0] == '~') REJECT;
18491862
addOutput(yyscanner,yytext);
1850-
QCString text(yytext);
1851-
if (yytext[0] == '\"') yyextra->fileName = text.mid(1,text.length()-2);
1852-
else yyextra->fileName = yytext;
1863+
yyextra->fileName = tmp;
18531864
if (YY_START == IFile)
18541865
{
18551866
BEGIN(Comment);
@@ -2143,6 +2154,8 @@ STopt [^\n@\\]*
21432154
/* ----- handle arguments of the subpage command ------- */
21442155
21452156
<SubpageLabel>{FILE} { // first argument
2157+
QCString tmp = stripQuotes(yytext);
2158+
if (tmp[0] == '~') REJECT;
21462159
addOutput(yyscanner,yytext);
21472160
// we add subpage labels as a kind of "inheritance" relation to prevent
21482161
// needing to add another list to the Entry class.

src/doctokenizer.l

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ ATTRIB {ATTRNAME}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><
198198
URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=\x80-\xFF]
199199
URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+
200200
URLPROTOCOL ("http:"|"https:"|"ftp:"|"ftps:"|"sftp:"|"file:"|"news:"|"irc:"|"ircs:")
201-
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
202-
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
201+
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@~]
202+
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@~]
203203
FILECHARS {FILEICHAR}*{FILEECHAR}+
204204
HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
205205
VFILEMASK {FILECHARS}("."{FILECHARS})*
@@ -260,8 +260,8 @@ REFWORD2_NOCV {REFWORD2_PRE}("("{FUNCPART}")")?
260260
REFWORD3 ({ID}":")*{ID}":"?
261261
REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOP2}))
262262
REFWORD4 {REFWORD4_NOCV}{CVSPEC}?
263-
REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4}
264-
REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
263+
REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4}
264+
REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
265265
RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revision"|"Source"|"State")":"[^:\n$][^\n$]*"$"
266266
LINENR {BLANK}*([1-9][0-9]*|"0"|"-1")
267267

@@ -897,19 +897,31 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
897897
return Token::make_RetVal_OK();
898898
}
899899
<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/{ID}"=" { // case 2: plain file name specified followed by an attribute
900-
yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
900+
QCString tmp = yytext;
901+
tmp = tmp.stripWhiteSpace();
902+
if (tmp[0] == '~') REJECT;
903+
yyextra->token.sectionId = tmp;
901904
return Token::make_RetVal_OK();
902905
}
903906
<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}+/"\"" { // case 3: plain file name specified followed by a quoted title
904-
yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
907+
QCString tmp = yytext;
908+
tmp = tmp.stripWhiteSpace();
909+
if (tmp[0] == '~') REJECT;
910+
yyextra->token.sectionId = tmp;
905911
return Token::make_RetVal_OK();
906912
}
907913
<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/\n { // case 4: plain file name specified without title or attributes
908-
yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
914+
QCString tmp = yytext;
915+
tmp = tmp.stripWhiteSpace();
916+
if (tmp[0] == '~') REJECT;
917+
yyextra->token.sectionId = tmp;
909918
return Token::make_RetVal_OK();
910919
}
911920
<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANKopt}/"\\ilinebr" { // case 5: plain file name specified without title or attributes
912-
yyextra->token.sectionId = QCString(yytext).stripWhiteSpace();
921+
QCString tmp = yytext;
922+
tmp = tmp.stripWhiteSpace();
923+
if (tmp[0] == '~') REJECT;
924+
yyextra->token.sectionId = tmp;
913925
return Token::make_RetVal_OK();
914926
}
915927
<St_PlantUMLOpt>"\\ilinebr" |
@@ -1090,14 +1102,29 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
10901102
unput(*yytext);
10911103
return Token::make_TK_NONE();
10921104
}
1105+
<St_Ref>{FILEMASK}/{BLANK}("const")[a-z_A-Z0-9] { // see bug776988
1106+
if (yytext[0] == '~') REJECT;
1107+
yyextra->token.name=yytext;
1108+
return Token::make_TK_WORD();
1109+
}
10931110
<St_Ref>{REFWORD_NOCV}/{BLANK}("const")[a-z_A-Z0-9] { // see bug776988
10941111
yyextra->token.name=yytext;
10951112
return Token::make_TK_WORD();
10961113
}
1114+
<St_Ref>{FILEMASK}/{BLANK}("volatile")[a-z_A-Z0-9] { // see bug776988
1115+
if (yytext[0] == '~') REJECT;
1116+
yyextra->token.name=yytext;
1117+
return Token::make_TK_WORD();
1118+
}
10971119
<St_Ref>{REFWORD_NOCV}/{BLANK}("volatile")[a-z_A-Z0-9] { // see bug776988
10981120
yyextra->token.name=yytext;
10991121
return Token::make_TK_WORD();
11001122
}
1123+
<St_Ref>{FILEMASK} { // label to refer to
1124+
if (yytext[0] == '~') REJECT;
1125+
yyextra->token.name=yytext;
1126+
return Token::make_TK_WORD();
1127+
}
11011128
<St_Ref>{REFWORD} { // label to refer to
11021129
yyextra->token.name=yytext;
11031130
return Token::make_TK_WORD();
@@ -1129,7 +1156,14 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
11291156
<St_IntRef>{BLANK}+"\"" {
11301157
BEGIN(St_Ref2);
11311158
}
1132-
<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK}|{FILEMASK} {
1159+
<St_SetScope>{FILEMASK} {
1160+
QCString tmp = yytext;
1161+
tmp = tmp.stripWhiteSpace();
1162+
if (tmp[0] == '~') REJECT;
1163+
yyextra->token.name = tmp;
1164+
return Token::make_TK_WORD();
1165+
}
1166+
<St_SetScope>({SCOPEMASK}|{ANONNS}){BLANK} {
11331167
yyextra->token.name = yytext;
11341168
yyextra->token.name = yyextra->token.name.stripWhiteSpace();
11351169
return Token::make_TK_WORD();
@@ -1319,7 +1353,10 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
13191353
return Token::make_TK_NONE();
13201354
}
13211355
<St_IFile>{BLANK}*{FILEMASK} {
1322-
yyextra->fileName = QCString(yytext).stripWhiteSpace();
1356+
QCString tmp = yytext;
1357+
tmp = tmp.stripWhiteSpace();
1358+
if (tmp[0] == '~') REJECT;
1359+
yyextra->fileName = tmp;
13231360
return Token::make_TK_WORD();
13241361
}
13251362
<St_IFile>{BLANK}*"\""[^\n\"]+"\"" {
@@ -1329,7 +1366,10 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
13291366
return Token::make_TK_WORD();
13301367
}
13311368
<St_File>{FILEMASK} {
1332-
yyextra->token.name = yytext;
1369+
QCString tmp = yytext;
1370+
tmp = tmp.stripWhiteSpace();
1371+
if (tmp[0] == '~') REJECT;
1372+
yyextra->token.name = tmp;
13331373
return Token::make_TK_WORD();
13341374
}
13351375
<St_File>"\""[^\n\"]+"\"" {
@@ -1352,6 +1392,11 @@ SHOWDATE ([0-9]{4}"-"[0-9]{1,2}"-"[0-9]{1,2})?({WS}*[0-9]{1,2}":"[0-9]{1,2}(":"[
13521392
<St_Pattern>. {
13531393
yyextra->token.name += yytext;
13541394
}
1395+
<St_Link>{FILEMASK} {
1396+
if (yytext[0] == '~') REJECT;
1397+
yyextra->token.name = yytext;
1398+
return Token::make_TK_WORD();
1399+
}
13551400
<St_Link>{LINKMASK}|{REFWORD} {
13561401
yyextra->token.name = yytext;
13571402
return Token::make_TK_WORD();

src/fortranscanner.l

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ PREFIX ((NON_)?RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,4}((NON
311311
SCOPENAME ({ID}{BS}"::"{BS})*
312312

313313
LINENR {B}*[1-9][0-9]*
314-
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
315-
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
314+
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@~]
315+
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@~]
316316
FILECHARS {FILEICHAR}*{FILEECHAR}+
317317
HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
318318
VFILEMASK {FILECHARS}("."{FILECHARS})*
@@ -1452,8 +1452,10 @@ private {
14521452
yyextra->docBlock += yytext;
14531453
}
14541454
<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
1455-
yyextra->fileName = &yytext[6];
1456-
yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1455+
QCString tmp = &yytext[6];
1456+
tmp = tmp.stripWhiteSpace();
1457+
if (tmp[0] == '~') REJECT;
1458+
yyextra->fileName = tmp;
14571459
yyextra->docBlock += yytext;
14581460
}
14591461
<DocBlock>{CMD}"iline"{LINENR}/[\n\.] |

src/pyscanner.l

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ SCRIPTCOMMENT "#!".*
204204
STARTDOCSYMS "##"
205205
206206
LINENR {B}*[1-9][0-9]*
207-
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
208-
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
207+
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@~]
208+
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@~]
209209
FILECHARS {FILEICHAR}*{FILEECHAR}+
210210
HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
211211
VFILEMASK {FILECHARS}("."{FILECHARS})*
@@ -1499,8 +1499,10 @@ ID [a-z_A-Z%]+{IDSYM}*
14991499
yyextra->docBlock+=yytext;
15001500
}
15011501
{CMD}"ifile"{B}+{FILEMASK} {
1502-
yyextra->fileName = &yytext[6];
1503-
yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1502+
QCString tmp = &yytext[6];
1503+
tmp = tmp.stripWhiteSpace();
1504+
if (tmp[0] == '~') REJECT;
1505+
yyextra->fileName = tmp;
15041506
yyextra->docBlock+=yytext;
15051507
}
15061508
{CMD}"iline"{LINENR}/[\n\.] |
@@ -1543,8 +1545,10 @@ ID [a-z_A-Z%]+{IDSYM}*
15431545
yyextra->docBlock+=yytext;
15441546
}
15451547
{CMD}"ifile"{B}+{FILEMASK} {
1546-
yyextra->fileName = &yytext[6];
1547-
yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1548+
QCString tmp = &yytext[6];
1549+
tmp = tmp.stripWhiteSpace();
1550+
if (tmp[0] == '~') REJECT;
1551+
yyextra->fileName = tmp;
15481552
yyextra->docBlock+=yytext;
15491553
}
15501554
{CMD}"iline"{LINENR}/[\n\.] |

src/scanner.l

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
290290
FUNCOP "operator"("()"|"[]"|{B}+[^;\n]+)
291291
MODULE_ID ({ID}".")*{ID}
292292
LINENR {B}*[1-9][0-9]*
293-
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
294-
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
293+
FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@~]
294+
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@~]
295295
FILECHARS {FILEICHAR}*{FILEECHAR}+
296296
HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
297297
VFILEMASK {FILECHARS}("."{FILECHARS})*
@@ -7092,8 +7092,10 @@ NONLopt [^\n]*
70927092
yyextra->docBlock << yytext;
70937093
}
70947094
<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
7095-
yyextra->fileName = &yytext[6];
7096-
yyextra->fileName = yyextra->fileName.stripWhiteSpace();
7095+
QCString tmp = &yytext[6];
7096+
tmp = tmp.stripWhiteSpace();
7097+
if (tmp[0] == '~') REJECT;
7098+
yyextra->fileName = tmp;
70977099
yyextra->docBlock << yytext;
70987100
}
70997101
<DocBlock>{CMD}"iline"{LINENR}{B} {

0 commit comments

Comments
 (0)