Rolf B: „Bildschirmgr%C3%B6%C3%9Fe“ - wie bitte?

problematische Seite

Hallo,

die "Im Forum fragen" Funktion des Wiki hatte einen blöden Bug, der dem Forum den Artikelnamen doppelt prozentcodiert übermittelte. Die Folge war, dass die betreffenden Zeichen im Betreff des Postings dann prozentcodiert angezeigt wurden, so wie „Bildschirmgr%C3%B6%C3%9Fe“ statt „Bildschirmgröße“ im Betreff dieses Artikels.

(Hinweis: Ich habe versucht, Mudguards Hinweis einzuarbeiten)

Was für mich ein Anlass ist, darüber zu sinnieren, dass Maskierungen zwecks Kontextwechsel gut gemeint sein können, aber immer mit der nötigen Prise Salz genossen werden müssen. Und ich kann ein bisschen davon erzählen, was beim Makeover so alles passiert.

Die fragliche Stelle hat eine längere Historie. Der Autor dieser Funktion hatte ursprünglich den Text der h1-Überschrift der Seite herangezogen, um den Link zum Forum zu generieren. Diese wurde in die Pfadteile zerlegt, die Teile mit encodeURIComponent %-codiert und alles zusammen mit "https://wiki.selfhtml.org/wiki/" zusammengefügt. So weit, so gut, aber dies wurde dann mittels $.param[1] zu der URL montiert, mit der das Forum zum Erstellen des neuen Beitrags aufgefordert wurde. Und $.param führt eine eigene %-Codierung durch, und damit wurden die Maskierungs-Prozentzeichen maskiert.

Das heißt also: Im Artikelnamen steht "größe". Frage ich das aus der URL der Seite ab, bekomme ich vom Location API die %-codierten UTF-8 Bytes: "gr%C3%B6%C3%9Fe". Speichere ich das in $.params (oder URLSearchParams), codiert der mir die Prozentzeichen nochmal und am Ende steht "gr%25C3%25B6%25C3%259Fe" im "Fragen"-Link. Wird der Link geklickt, empfängt CForum "gr%25C3%25B6%25C3%259Fe" und decodiert das zu "gr%C3%B6%C3%9Fe". Richtig wäre hingegen, "gr%C3%B6%C3%9Fe" zu senden, so dass CForum daraus "größe" machen kann.

Was ich nicht weiß: das war 2016, und die damalige CForum-Version hat das möglicherweise so gebraucht. Oder unter der Hand nachgebessert. Man findet im Forum auch nur ganz wenige Postings, die Kandidaten für den Fehler sind, und die meisten enthalten korrekte Sonderzeichen. Es ist also auch nicht auszuschließen, dass der Fehler anfangs gar nicht auffiel, aber Matthias (Sch.) meinte, das sei eigentlich immer so gewesen und er hätte die Postings editiert.

Jedenfalls gab's einige Weiterentwicklungen dieser Stelle, die Permalinks kamen hinzu, aber der überzählige Kontextwechsel blieb. Es ist auch gar nicht so einfach, ihn zu vermeiden, weil es einfach kein Mediawiki- oder Browser-API zu geben scheint, das die URL der Seite uncodiert liefert.

Für den Namen der angefragten Seite geht's noch, dafür gibt es ein API, aber wenn man die URL nicht an Mediawiki vorbei aus dem Seitennamen bauen will, ist das Ergebnis immer %-codiert. Woraus folgt, dass ich einen vom System netterweise angebotenen Kontextwechsel gleich wieder rückgängig machen muss, damit der dann wieder vorgenommen wird:

const headingparts = mw.config.get('wgTitle').split('/'),
      frage_parms = new URLSearchParams([
        [ 'message[subject]', 
          'Frage zum Wiki-Artikel „' + headingparts[headingparts.length-1] + '“'
        ],
        [ 'message[problematic_site]', 
          decodeURI(location.origin + location.pathname)
        ],
        ...
      ]);

(Im Makeover, der noch im Testwiki steckt, kommt da mw.util.getUrl hin, aber dafür muss ich Abhängigkeiten zu mw.util beachten und dafür habe ich im Hauptwiki noch nicht die Infrastruktur)

(Durch Einsatz von wgTitle statt wgPageName werden auch Artikel mit Leerstellen im Lemma korrekt übergeben)

(Ja, statt [headingparts.length-1] könnte ich .at(-1) nehmen - aber das ist ES2022 und selbst für die die letzte Compatibility-Liste von Mediawiki zu neu. Und ich will nicht anfangen, das Wiki zu polyfillen)

Rolf

--
sumpsi - posui - obstruxi

  1. die jQuery-Antwort von 2007 auf eine Frage, die nativ erst 2014 mit URLSearchParams beantwortet wurde ↩︎

  1. problematische Seite

    Hi,

    die "Im Forum fragen" Funktion des Wiki hatte einen blöden Bug, der dem Forum den Artikelnamen doppelt prozentcodiert übermittelte.

    nur zur Klarstellung: das im Betreff ist nicht doppelt prozentcodiert, das sind 2 Zeichen, die in UTF-8 codiert jeweils 2 Bytes ergeben, nämlich ein UTF-8-codiertes ö (uC3B6) und ein UTF-8-codiertes ß (uC39f).

    cu,
    Andreas a/k/a MudGuard

    [Edit Rolf B: Dieser Beitrag mag nun obsolet erscheinen. Ich habe mich bemüht, die angesprochene Unklarkeit zu beheben.]

    1. problematische Seite

      Hallo MudGuard,

      nein nein, ganz so blöd bin ich ja nicht 😉. Ich habe es vielleicht ungeschickt formuliert.

      Damit im Forentitel korrekt Bildschirmgröße steht, muss ich in der Anforderungs-URL das ö und das ß als UTF-8 codieren und die Bytecodes als %-Sequenz übermitteln. Dann funktioniert das auch.

      Aber weil ich vom Location API bereits einen %-codierten String bekomme, der dann von $.param bzw. URLSearchParams nochmal codiert wird, entsteht Bildschirmgr%25C3%25B6%25C3%259Fe Und daraufhin zeigt das Forum unerwünschterweise Bildschirmgr%C3%B6%C3%9Fe an. Was kein Forumsfehler ist, es tut, was man von ihm bestellt hat.

      Wenn ich zunächst einen decodeURI mache, übergebe ich an URLSearchParams einen Unicode-String mit den Unicode-Codepoints für ö und ß. Und URLSearchParams wandelt das in UTF-8 und codiert die Bytes oberhalb von 0x7f per Prozentschreibweise. Wie es halt sein muss.

      Oder gibt's mittlerweile Unicode-URLs, wo ich die UTF-8 Bytes einfach so reinstellen kann? Wenn ja, dann weiß URLSearchParams nichts davon, d.h. unter Verwendung der passenden JavaScript APIs wäre sowas nicht herstellbar.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. problematische Seite

        Hi,

        nein nein, ganz so blöd bin ich ja nicht 😉.

        Das wollte ich auch nicht andeuten.

        Ich habe es vielleicht ungeschickt formuliert.

        Aber dem hier entgegenwirken.

        cu,
        Andreas a/k/a MudGuard

        1. problematische Seite

          Hallo MudGuard,

          Das wollte ich auch nicht andeuten.

          Weiß schon. Deshalb ja der 😉.

          Danke für den Hinweis auf die möglichen Verständnisprobleme.

          Rolf

          --
          sumpsi - posui - obstruxi
  2. problematische Seite

    Ein Nachtrag:

    tatsächlich kann ich im href-Attribut eines a Elements auch URLs eintragen, die deutlich weniger codiert sind. Ich kann dem href-Attribut auch diese URL zuweisen (Zeilenumbrüche von mir zur Lesbarkeit):

    …/new
    ?message[problematic_site]=https://wiki.selfhtml.org/wiki/Bildschirmgröße
    &message[subject]=Frage+zum+Wiki-Artikel+„Bildschirmgröße“? 
    

    und das funktioniert - obwohl es nicht ganz richtig ist (und es den Artikel nicht gibt). Die eckigen Klammern sind wurden 2005 von rfc3986 als "general delimiters" im Query-String verboten, Doppelpunkt und Schrägstrich hingegen sind erlaubt. Da müsste also eigentlich %5B und %5D stehen. Warum [] verboten ist, erschließt sich mir nicht, die markieren eigentlich nur eine IPv6 im Host-Teil.

    Die HTML Spec besagt jedenfalls, dass alle Unicode-Codepoints ab \u00a0 in URLs zulässig sind (was heißt: dort, wo URLs in einem HTML-Attribut abgelegt werden) und nicht maskiert werden müssen. Auf der Leitung werden daraus trotzdem wieder die %-codierten UTF-8 Bytes - zumindest sagt das mein Netzwerk-Trace.

    All das ignoriert URLSearchParams, es codiert gnadenlos jedes Zeichen, das im UTF-8 mehr als 2 Bytes braucht, in Prozentform. Um rückwärtskompatibel zu Uralt-Servern zu sein, nehme ich an, und um das Internetmantra zu befolgen: „Folge beim Schreiben strikt den Regeln und verzeihe beim Lesen möglichst viele Fehler.“

    Rolf

    --
    sumpsi - posui - obstruxi