A link annotation listed twice in one page's /Annots, or by two pages, kept its later references after the first one stripped its external action, leaving inert links on the page. Every reference to a link that ends up with no action and no /Dest is now removed. A shared link counts once in external_links.
When an action to another document was removed and its /Next list
started with a null or a reference to something other than an action,
that entry became the head of the chain, and the actions after it, such
as a web link, were dropped with it. Leading entries that are not
action dictionaries are now skipped. The Settings::discard_external_refs
doc comment lists every action type the option removes.
PDF Optimizer > Discard User Data gets "Discard external cross-references",
off by default. It takes GoToR, GoToE, Launch and ImportData actions, and
Thread actions with an /F, out of the actions of link annotations and
bookmarks, and the actions chained after one through /Next take its place
in order. Other annotations, such as form fields, keep their actions. A
link left with no action and no /Dest is removed from its page; when the
link is an indirect object, that object is rewritten without the action
for anything else that refers to it. A bookmark keeps its title, place and
children, including a bookmark stored directly inside another one. Links
within the document and web links stay. An indirect action that changes
is written as a new indirect object, except the first action left at the
head of an /A, which is copied into the /A directly when other actions
follow it. Objects that use the old action keep it. An /A with more than
100,000 values to check, or one that opens another document and needs
more than 100,000 values to rewrite, stops the optimization with
OptimizeError::ExternalRefLimit, and so does an outline of more than
100,000 bookmarks.
doc_optimize takes discard_external_refs and reports external_links and
external_bookmarks.