Bug #18897
closedUmlauts get broken in shortcut menu while renaming the shortcut
0%
Description
When you edit an item in the new shortcut menu and use special chars in the name (e.g. äöü), these umlauts get brocken (output is like äöü)
How to reproduce:
- create a new shortcut e.g. in Page-Modul by clicking the shortcut-icon at the bottom of the right frame
- open the shortcut dropdown menu at the top
- edit the new item
- use any special char in the name (e.g. ä ö ü)
- click OK to save
- the the brocken umlauts
Whats the reson?
The javascript of the menu uses prototypes "Ajax.Request" to send the new name to the Server.
"Ajax.Request" uses "encodeURIcomponent" to urlencode the Strings in the form to make them safe to send by GET or POST
Unfortunately "encodeURIcomponent" ALWAY uses UTF-8 as encoding and does not care which charset is used on the current page.
So the server/php-script recieves an UTF-8 encoded string which is expected to be ISO-8859-1 (which is the defualt for the backend).
The script saves the utf-8-string to the database as it is, but later it is read and delivered as an ISO-8859-string
THIS ALSO HAPPENS IN
- t3editor (here i found a solution: see #8264)
- web>access (reported by susanne moog in #8578)
- and everywhere where teh new ajax.php/typo3ajax is used to RECIEVE data via Ajax.Request
How to solve?
In my patch for #8264 i check the used charset in the incoming Ajaxrequest and compare it to the charset used in the backend. If needed all POST-data would be converted.
Should this be handeled by the ajax.php for all requests?
If yes, i can make a patch for this
IMHO this should be fixed for 4.2.1
(issue imported from #M8591)
Files
Updated by Tobias Liebig over 16 years ago
please add relations to #8264 and #8578
Updated by Tobias Liebig over 16 years ago
forgot to say:
all this does not happen, if you use forceCharset = utf-8 for the Backend!
Updated by Tobias Liebig over 16 years ago
This is my idea which could be implemented in class.typo3ajax.php
// define default values as class members
/**
* Ajax requests are always expected in UTF-8 (as prototype uses utf-8/encodeURIcomponent for Ajax.Request)
*
* @var string
*/
protected $ajaxRequestCharset = 'utf-8';
/**
* The Backend/Database uses ISO-8859-1 by default (see template.php).
* This can be overwritten by 'forceCharset'
*
* @var string
*/
protected $backendCharset = 'iso-8859-1';
...
// get charset from current ajax request (which is expected to be utf-8)
preg_match('/.*; charset=(.*)$/i', $_SERVER["CONTENT_TYPE"], $match);
$this->ajaxRequestCharset = $match[1] ? strtolower($match[1]) : $this->ajaxRequestCharset;
// get charset used in the backend/database
$this->backendCharset = $GLOBALS['LANG']->charSet ? $GLOBALS['LANG']->charSet : $this->backendCharset;
...
// for every POST and GET-Var (recursive!)
// convert to correct charset if needed
$val = $GLOBALS['LANG']->csConvObj->conv($val, $this->ajaxRequestCharset, $this->backendCharset);
any comments welcome!
Updated by Benni Mack over 16 years ago
Hey Tobi,
good stuff. However, I just thought of something else... can it also be related to the Prototype AJAX.Options.charset variable, which is set to UTF-8 by default? (see http://www.prototypejs.org/api/ajax/options)
Anyway, the approach makes sense, however I always dislike introducing another $charset variable (I worked on this UTF-8 by default, where you have DB charset, Content Charset, Client Charset, Backend Charset)...
Anyway, the solution makes sense, we should run it by Masi however. Could you send him an email?
Another solution would be: do the switching within Javascript
1. Have a global "TYPO3BackendCharset = ..." variable in backend.php
2. Add this to common.js, to make encodeUIRComponent do whatever it should depending on the charset
var classicEncURIcomp = encodeURIcomponent;
function encodeURIcomponent(str) {
if (TYPO3BackendCharset == 'utf8') {
return classicEncURIcomp(str);
} else {
return escape(str);
}
}
Also, for both options, we need to document this in the source code why we do such complicated things. :)
Updated by Tobias Liebig over 16 years ago
Hej Benni,
thanks for your comment.
i didn't know "AJAX.Options.charset" yet. i'll have a look on it.
Your solution to replace the "encodeURIcomponent" by "escape" if the Charset is not "utf-8" would fail.
i had the same idea to solve #6812, but there i a problem with "escape".
"escape" does not encode "+". Unfortunately a "+" will become a " " (space) in urlEncoding. This caused #8264
I my option (after a short discussion in the core-list with Dmitry and Masi) the best solution would be to handle the encoding on server-side.
i will prepare a patch and then get in touch with Masi for further discussion.
Updated by Benni Mack over 16 years ago
As talked with you over PM, I agree. However (to fix the problem where it initiates and to nag in this client side solution), we could create a customized encodeURIcomponent for ourselves, doing strreplace on the string ourselves, if it's a different charset. I somehow feel we will need the charset stuff a bit more on the client side at some point.
Updated by Tobias Liebig over 16 years ago
Patch added.
i'll post it in the core list soon
Updated by Tobias Liebig over 16 years ago
Posts in Ajax.requests (prototype) are always UTF-8 encoded, but they are expected to be encoded like the backend is (iso-8859-1 by default).
This caused special chars to get mixed up (happes in shortcut menu and in the t3editor)
Solution:
Recode/convert all GET and POST values for every Ajax.Request where the content-type charset does not match with the backend charset
this is handled by class.typo3ajax.php to ensure it works correct for every ajax-call which uses the new ajax.php
Note:
For the t3editor i introduce an "workaround" for this issue earlier. There i tried to to solve it on client side (javascript) by replacing "encodeURIcomponent" by "escape". Unfortunately "escape" does not encode "+" correct. see #18897. This workaround should be removed. See my next post.
Note II:
This issue is related for all requests which use "ajax.php/class.typo3ajax.php" in the backend.
Most of them do not send any content, but just request some code from the server. So they had no problem at all.
Any ajax request, which sends content (e.g. input-values, names) to the server, would have the same problem and thus should be tested.
What/Howto test:
shortcut menu: see bugtracker #18897
t3editor: depends on another patch: see #18897 (next post)
any other case which uses ajax.php/class.typo3ajax.php
some testcases:
Use default charset (iso-8859-1) for the backend (by not setting forceCharset)
Use UTF-8 for the backend (set forceCharset to utf-8)
Use any other charset
Use special chars (ä ü ö) and a plus sign "+" in the shortcut title
...