titlesec icon indicating copy to clipboard operation
titlesec copied to clipboard

`\@currentlabelname` is not correctly sanitized

Open u-fischer opened this issue 2 years ago • 5 comments

titlesec defines \@currentlabelname in \ttl@straight@i but doesn't sanitized the argument.

\def\ttl@straight@i#1[#2]#3{%
  \def\@currentlabelname{#2}% for nameref
  \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}%
  \let\ttl@savewrite\@empty
  \def\ttl@savetitle{#3}%
  \gdef\thetitle{\csname the#1\endcsname}%
  \if@noskipsec \leavevmode \fi
  \par
  \ttl@labelling{#1}{#2}%
  \ttl@startargs\ttl@straight@ii{#1}{#3}}

If nameref is loaded this more or less works, but without it it breaks in a current LaTeX which now stores the labelname too:

\documentclass{article}
\usepackage{titlesec}
\begin{document}
\section{a\label{b}}
\end{document}

gives

! TeX capacity exceeded, sorry [input stack size=10000].
\protect ->\noexpand \protect 
                              \noexpand 
l.217 \section{a\label{b}}

titlesec could load the gettitlestring package and then do:

\GetTitleString{#2}%
\let\@currentlabelname\GetTitleStringResult

u-fischer avatar Aug 02 '23 14:08 u-fischer

I’m reopening this issue because it won’t get fixed in the short or medium term.

jbezos avatar Oct 26 '23 16:10 jbezos

@u-fischer this is possibly enough, without introducing a new package dependency?

\documentclass{article}

\usepackage{titlesec}

\makeatletter
\def\removelabel#1\label#2#3\label#4\relax{#1#3}
\def\ttl@straight@i#1[#2]#3{%
  \expandafter\def\expandafter\@currentlabelname\expandafter{%
         \removelabel#2\label{}\label{}\relax}% for nameref
  \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}%
  \let\ttl@savewrite\@empty
  \def\ttl@savetitle{#3}%
  \gdef\thetitle{\csname the#1\endcsname}%
  \if@noskipsec \leavevmode \fi
  \par
  \ttl@labelling{#1}{#2}%
  \ttl@startargs\ttl@straight@ii{#1}{#3}}
\makeatother
\begin{document}

\section{a\label{b}}

\end{document}

davidcarlisle avatar Apr 08 '24 21:04 davidcarlisle

It would fix the label case, but generally I think it would be better if not every package defines its own sanitizing variant.

u-fischer avatar Apr 08 '24 22:04 u-fischer

@u-fischer hmm we could also fix this in the kernel by copying the normalization used by \addtocontents to \label

\documentclass{article}

\usepackage{titlesec}

\makeatletter
\def\label#1{\@bsphack
  \begingroup
  \UseHookWithArguments{label}{1}{#1}%
  \protected@write\@auxout{%
    \let\label\@gobble \let\index\@gobble \let\glossary\@gobble% new
  }%
         {\string\newlabel{#1}{{\@currentlabel}{\thepage}%
          {\@currentlabelname}{\@currentHref}{\@kernel@reserved@label@data}}}%
  \endgroup
  \@esphack}
\makeatother
\begin{document}

\section{a\label{b}}

\end{document}

davidcarlisle avatar Apr 08 '24 23:04 davidcarlisle

@davidcarlisle that is a good idea.

u-fischer avatar Apr 09 '24 09:04 u-fischer