Skip to content

Custom link label gets double-encoded with HTML entities on each save when it contains special characters #89

Description

@Daaaaad

Bug description

When editing a custom link in the main menu (BO > Modules > ps_mainmenu > Custom links), the label is re-encoded as HTML entities on every save. The encoding stacks up at each edit cycle, eventually rendering the label unreadable in the BO and on the front-end.

Steps to reproduce

  1. Install / enable ps_mainmenu.
  2. In its configuration page, add a custom link with a label containing a special character. Example label: À propos (with accented capital À).
  3. Save the link.
  4. Re-open the link for editing (click "Edit" in the link list).
  5. Observe the label field in the edit form.
  6. Save again without modifying anything.
  7. Repeat the edit/save cycle a few times.

Expected behavior

The label keeps its original form (À propos) across saves, both in the BO edit form and in the DB. No HTML entity transformation should happen.

Actual behavior

  • After the first save: the label is stored as À propos in the DB (ps_linksmenutop_lang.label) and shown as À propos in the list of links.
  • When re-opening the edit form, the input pre-fills with À propos (raw, not decoded).
  • On the next save, it becomes À propos.
  • On the next: À propos.
  • And so on, ad infinitum.

This affects every special character that gets HTML-entity-encoded (accents, ampersands, quotes, etc.).

Where the issue seems to be

In ps_mainmenu.php, method getAddLinkFieldsValues() (around line 1355-1364 in v2.3.6):

if (Tools::isSubmit('updatelinksmenutop')) {
    $link = Ps_MenuTopLinks::getLinkLang(Tools::getValue('id_linksmenutop'), (int) Shop::getContextShopID());

    foreach ($link['link'] as $key => $label) {
        $link['link'][$key] = Tools::htmlentitiesDecodeUTF8($label);
    }

    $links_label_edit = $link['link'];
    $labels_edit = $link['label'];   // <-- label is NOT decoded here
    ...
}

Tools::htmlentitiesDecodeUTF8() is called on $link['link'] (the URL) before pre-filling the edit form, but the same decoding is not applied to $link['label']. As a result, the label keeps its DB-encoded form when re-displayed in the form input, and is re-encoded on the next save, causing the stacking effect.

Environment

  • PrestaShop: 9.1
  • ps_mainmenu: 2.3.6
  • PHP: 8.4
  • Theme: custom (Bootstrap 5 / Hummingbird-based), but the bug is reproducible on the default theme too (the BO is the affected surface, not the front).

Side note

The same kind of mismatch may exist in other parts of the module (link list rendering, etc.). Worth a broader audit while the affected method is being touched.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions