[PHP] htmlspecialchars -> Turkse karakters negeren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Hey,

Om html in de berichten te negeren (en dus niet te laten uitvoeren) gebruik ik htmlspecialchars om deze om te zetten in zichtbare html output.
Nu is het zo dat ik Turkse karakters wel wil weergeven (Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё), echter worden deze ook ge-escaped door de functie htmlspecialchars.

Nu heb ik gezocht op internet naar een oplossing voor dit probleem, echter (helaas) zonder resultaat.

De turkse karakters worden op deze manier opgeslagen in de database:

code:
1
Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё


Wanneer ik deze dus letterlijk output gaat het goed, echter is het dan zeer onveilig (XSS aanvallen). Wanneer ik htmlspecialchars gebruik worden bovenstaande karakters dus letterlijk zo ge-ouput (logisch).

Weet iemand hoe ik dit kan oplossen? (ik gebruik UTF charset)

Edit: Ik zie dat het hier op GOT wel goed gaat met Turkse karakters.

[ Voor 10% gewijzigd door radem205 op 12-05-2010 22:13 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ehh, de data staat niet goed opgeslagen in je database, dus eerst html_entity_decode gebruiken. Liever zorg je dat je database geen htmlentities bevat... :p

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Dus html_entity_decode() moet ik gebruiken alvorens de data in de database te stoppen?
Want bij het toevoegen van data in de database worden deze karakters automatisch omgezet in htmlentities (dus zonder tussenkomst van een code). Is dit abnormaal?

Maar dan blijft het euvel bestaan dat htmlspecialchars later de speciale karakters weer omzet in htmlentities, of doe ik iets verkeerd?

[ Voor 21% gewijzigd door radem205 op 12-05-2010 22:25 ]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) (met dank aan RobIII natuurlijk).

Rücksichtlos alle data maar willekeurig encoden en escapen zorgt er niet voor dat het invoeren in de database en weer tonen op een webpagina automagisch goed gaat. Zorg dat op alle momenten de karakterencoding en -sets overeenkomen (html, http, php, sql) en je zal zien dat het allemaal goed gaat.

Je probeert nu een niet-bestaand probleem op te lossen met tools die daar niet voor zijn bedoeld.

[ Voor 8% gewijzigd door CodeCaster op 12-05-2010 22:27 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Het enige wat ik niet op UTF-8 charset had staan was de database tabel zelf. Maar die heb ik al meerdere keren omgezet naar UTF-8 met hetzelfde resultaat. Ik heb de meta tag op UTF-8 staan, php staat op UTF-8 en zelfs de verbinding met mysql heb ik op UTF-8 gezet, middels:

$sql = $db->query("SET NAMES 'utf8'");

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
@Codecaster : Dan ga je er wel vanuit dat de ( in 1e instantie ) aangeleverde data volgens de juiste encoding loopt.

Ik heb ondertussen genoeg db-dumps gekregen met wisselende encodings ( of andere encodings dan opgegeven ), redelijk wat browsers gezien die gewoon encoding regels negeren.

Het gaat niet allemaal goed, alhoewel je het wel terug kan dringen tot het minimum

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
radem205 schreef op woensdag 12 mei 2010 @ 22:22:
Dus html_entity_decode() moet ik gebruiken alvorens de data in de database te stoppen?
Want bij het toevoegen van data in de database worden deze karakters automatisch omgezet in htmlentities (dus zonder tussenkomst van een code). Is dit abnormaal?
Ja, dit is abnormaal. html_entity_decode() zou niet nodig moeten zijn voor het erin stoppen, als je gewoon de html-encodering overslaat. ;) Normaal staan er in ieder geval geen htmlentities in je database. Het is namelijk helemaal niet zeker of je wel html wil outputten. Misschien wil je wel ingraferen ofzo. :p

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
pedorus schreef op woensdag 12 mei 2010 @ 22:36:
[...]

Ja, dit is abnormaal. html_entity_decode() zou niet nodig moeten zijn voor het erin stoppen, als je gewoon de html-encodering overslaat. ;) Normaal staan er in ieder geval geen htmlentities in je database. Het is namelijk helemaal niet zeker of je wel html wil outputten. Misschien wil je wel ingraferen ofzo. :p
Haha. Maar wat kan dan de reden zijn van het omzetten naar htmlentities voordat de data in de database gestopt wordt? Want ik stop alle data rechtstreeks de database in (mbv PDO bindParam), dus zonder tussenkomst van andere codes die dit kunnen veroorzaken.

Edit: Ik heb de velden nu op UTF8_turkish_ci gezet en nu werkt het al beter, echter krijgt ik voor de Turkse karakters (zie startpost) de volgende data in de tabel:

Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё

Weet iemand welke charset ik nodig heb voor Turkse karakters? (het lijkt mij toch dat ik de goede charset heb (UTF8_turkish_ci). Welke database charset wordt hier op GOT gebruikt?

[ Voor 23% gewijzigd door radem205 op 12-05-2010 22:47 ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21-09 21:47

Creepy

Tactical Espionage Splatterer

Lees de link die codecaster geeft eens goed door. Ja, het is een lang verhaal maar het lost het probleem dat je nu hebt gewoon op ;)

Wat je nu ziet zijn bytes op een verkeerde manier getoond. Het lijkt erop alsof het als UTF-8 in de database staat maar niet als UTF-8 wordt opgehaald of niet als UTF-8 getoond. Ergens doe jij iets fout en dat los je niet zomaar op door een andere charset te kiezen, maar dat was je al verteld.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
radem205 schreef op woensdag 12 mei 2010 @ 22:39:
Haha. Maar wat kan dan de reden zijn van het omzetten naar htmlentities voordat de data in de database gestopt wordt? Want ik stop alle data rechtstreeks de database in (mbv PDO bindParam), dus zonder tussenkomst van andere codes die dit kunnen veroorzaken.
Geen flauw idee.
Edit: Ik heb de velden nu op UTF8_turkish_ci gezet en nu werkt het al beter, echter krijgt ik voor de Turkse karakters (zie startpost) de volgende data in de tabel:

Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё �
Lijkt me niet dat UTF8_turkish_ci uitmaakt, dat is een collatie (vergelijkingsmethode, bij turks is bijvoorbeeld de hoofdletter i anders als je case-insensitive vergelijk). Je doet hier in ieder geval een onnodige iconv('cp1252','utf-8',$var) oid terwijl je al utf-8 hebt.
Weet iemand welke charset ik nodig heb voor Turkse karakters? (het lijkt mij toch dat ik de goede charset heb (UTF8_turkish_ci).
Gewoon utf-8 volstaat.
Welke database charset wordt hier op GOT gebruikt?
Geen idee. T.net geeft ISO-8859-15 terug (ondanks dat ik vraag om ISO-8859-1 of utf-8).

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Na alles in de database omgezet te hebben naar UTF8_general_ci werkte het nog niet, maar na ook nog onderstaand te hebben verwijderd werkt het opeens wel:

$sql = $db->query("SET NAMES 'utf8'");

Vreemd, want deze code moet juist bijdragen aan een juiste charset toch?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Zonder volledige context valt daar weinig over te zeggen. Wat retourneert
SQL:
1
2
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

? Verder is 'SET NAMES' gevaarlijk in combinatie met bepaalde charsets (gbk) als quote/escape-functies moeten meeveranderen. mysql_real_escape_string update bijvoorbeeld niet, hoe het met pdo's quote zit weet ik niet.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Ik krijg als uitkomst dit:

collation_connection - utf8_general_ci
collation_database - utf8_general_ci
collation_server - latin1_swedish_ci

Dus alleen collation_server staat nog verkeerd in mijn ogen, toch? Is dit alleen aan te passen middels het config bestand van mysql?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Op zich boeit het niet zo hoe collation_server staat als collation_database gezet is:
The server character set and collation are used as default values if the database character set and collation are not specified in CREATE DATABASE statements. They have no other purpose.
Als het overigens om uitsluitend turks gaat, dan lijkt het me handig om overal (database, tabellen, kolommen, connectie) die collation te gebruiken, voor als je bijvoorbeeld case-insensitive wil vergelijken.

De output van de charsets was interessanter geweest. Als 'SET NAMES' daadwerkelijk een verkeerde invloed heeft, dan staan character_set_client en/of character_set_results niet op utf8. Dit kan weer komen omdat je bijvoorbeeld geen goede charset-header geeft, waardoor mysql nu een terechte conversie maakt.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:25

crisp

Devver

Pixelated

Ik zie hier een hoop gepraat worden over de database en UTF8, maar controleer eerst maar eens of je pagina's wel als UTF8 geserveert worden. Het feit dat je entities in je database hebt staan doet mij toch eerder denken aan een server-client probleem mbt charset waarbij de browser dan speciale tekens omzet naar entities alvorens die door te sturen naar de server.

Om dubbele encoding te voorkomen bij het gebruik van htmlspecialchars is er sinds PHP 5.2.3 een $double_encode parameter waarmee je dat kan voorkomen. Wij gebruiken op GoT iets soortgelijks aangezien onze hele backend nog met Latin 9 (ISO-8859-15) werkt, maar dat soort dingen zouden niet nodig zijn als de hele chain daadwerkelijk UTF8-based is.

[ Voor 7% gewijzigd door crisp op 14-05-2010 00:32 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
pedorus schreef op donderdag 13 mei 2010 @ 14:07:
Op zich boeit het niet zo hoe collation_server staat als collation_database gezet is:

[...]

Als het overigens om uitsluitend turks gaat, dan lijkt het me handig om overal (database, tabellen, kolommen, connectie) die collation te gebruiken, voor als je bijvoorbeeld case-insensitive wil vergelijken.

De output van de charsets was interessanter geweest. Als 'SET NAMES' daadwerkelijk een verkeerde invloed heeft, dan staan character_set_client en/of character_set_results niet op utf8. Dit kan weer komen omdat je bijvoorbeeld geen goede charset-header geeft, waardoor mysql nu een terechte conversie maakt.
Nog even terugkomend op bovenstaand:
Alles staat op UTF8(_general_ci), dus meta een header content-type in php en ook de mysql database:

collation_connection - utf8_general_ci
collation_database - utf8_general_ci
collation_server - latin1_swedish_ci (behalve deze, maar deze is niet belangrijk toch?)
character_set_client - utf8
character_set_results - utf8

Nu gebruik ik ook nog een $db->query("SET NAMES UTF8"); bovenaan elke pagina om de verbinding ook op UTF8 te zetten.

Wanneer ik via een tekstvak Turkse karakters invoer en deze direct toevoeg in de database dan komen de speciale tekens netjes in de database te staan.
Echter wanneer ik deze gegevens ophaal (om weer te geven) dan krijg ik in de plaats van de speciale karakters een vraagteken in de plaats (?).

Wanneer ik de $db->query("SET NAMES UTF8"); verwijder dan gaat het allemaal goed, echter krijg ik dan hele rare tekens in de database te staan, namelijk:


Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё

In plaats van:

Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё


Echter wanneer ik deze gegevens weergeef dan komen de juiste karakters weer in beeld.

Ik kan er nu even niet meer wijs uit worden waar het aan kan liggen en ik hoop dat iemand mij nog kan helpen met dit toch wel belangrijk probleem.

Edit: Wanneer ik met HTTP header in firefox de headers controleer dan staan die ook allemaal op UTF8.

[ Voor 3% gewijzigd door radem205 op 17-05-2010 21:43 ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Maak eens gewoon een simpele test-pagina waarop je kan invoeren en dan bij een submit op dezelfde pagina het resultaat toont ( via de dbase en daaronder gewoon de post-content ).

Want de hele keten staat nog niet compleet op utf-8...

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
radem205 schreef op maandag 17 mei 2010 @ 21:37:
collation_connection - utf8_general_ci
character_set_client - utf8
character_set_results - utf8
Was dit voor of na 'set names utf8'? Als dit al zo staat zou 'set names utf8' namelijk helemaal niks meer moeten doen, dus het lijkt me vreemd als dat verschil maakt. ;)
Wanneer ik via een tekstvak Turkse karakters invoer en deze direct toevoeg in de database dan komen de speciale tekens netjes in de database te staan.
Als in, er staat iets in de database, of als in dat het ook de juiste encoding heeft?
Echter wanneer ik deze gegevens ophaal (om weer te geven) dan krijg ik in de plaats van de speciale karakters een vraagteken in de plaats (?).
Is het nu misgegaan bij het ophalen, of bij het erin stoppen? Of gaat er bij beiden iets mis? Het lijkt me vrij simpel om even te testen bij het erin stoppen of je het correct terug kan echo-en, en of je het correct uit de db kan opvragen en terug kan echo-en.
Wanneer ik de $db->query("SET NAMES UTF8"); verwijder dan gaat het allemaal goed, echter krijg ik dan hele rare tekens in de database te staan, namelijk:


Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё �r

In plaats van:

Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё Ё
Staat de tabel of kolom toevallig op cp1252? Hier is in ieder geval zeer waarschijnlijk, zoals ik al eerder zei, een foute conversie van cp1252 naar utf-8 geweest terwijl het al in utf-8 stond. Test anders zelf maar uit:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php header('Content-Type: text/html; charset=utf-8'); ?>
<form action="<?php echo $_SERVER['SCRIPT_NAME']; ?>" method="post">
<textarea name="q" cols=100 rows=30>
<?php echo htmlspecialchars(iconv($_POST['from'],$_POST['to'],$_POST['q'])); ?>
</textarea><br>
<select name="from">
  <option selected>utf-8</option><option>cp1252</option><option>iso-8859-1</option>
  <option>iso-8859-15</option><option>cp866</option><option>cp1251</option>
  <option>koi8-r</option><option>big5</option><option>gb2312</option>
  <option>big5-hkscs</option><option>shift_jis</option><option>euc-jp</option>
</select>
<select name="to">
  <option selected>utf-8</option><option>cp1252</option><option>iso-8859-1</option>
  <option>iso-8859-15</option><option>cp866</option><option>cp1251</option>
  <option>koi8-r</option><option>big5</option><option>gb2312</option>
  <option>big5-hkscs</option><option>shift_jis</option><option>euc-jp</option>
</select>
<input type="submit" value="submit">
</form>

Ligt dit nu aan de manier waarop je je database opvraagt?

Verder valt me trouwens op dat Tweakers zich verslikt op
"Ş ș ü Ü ı ö Ö Ç ç ğ Ğ é É ё �br>" of wat het ook mogen wezen. Afhankelijk van hoe ik quote, krijg ik al dan niet br> of r of niks erachteraan...
Echter wanneer ik deze gegevens weergeef dan komen de juiste karakters weer in beeld.
Misschien gaat er wel niks mis en ligt het aan je andere manier van de db opvragen?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1