[Bug? Forma 2.4.x] Services_JSON, accenti

Installazione, configurazione generale, notifiche, API, lingue, problemi server
User avatar
max
FormaLms Guru
Posts: 2735
Joined: Thu Mar 01, 2012 10:41 am
Version: forma.lms 2.4
Contact:

Re: [Bug? Forma 2.4.x] Services_JSON, accenti

Post by max »

ciao, io ho appena fatto un test analogo su una 2.4.1: caratteri accentati e speciali vengono tutti visualizzati correttamente nella lista corsi

Su questa piattaforma c'è PHP 7.0.33
Io non riscontro dunque nessun problema. Il massimo che posso fare è segnalare la cosa a qualche collega, visto che non riesco a replicarlo non mi sento di aprire un ticket
Attachments
test.PNG
test.PNG (2.87 KiB) Viewed 2511 times
---------------------
Massimiliano Ferrari
Elearnit - Elearning e Knowledge Management
https://www.elearnit.net
https://www.linkedin.com/in/massimilianoferrari
m.ferrari[at]elearnit.net
Skype: m_ferrari_it
User avatar
CisterNino
FormaLms User
Posts: 72
Joined: Mon May 06, 2013 2:59 pm

Re: [Bug? Forma 2.4.x] Services_JSON, accenti

Post by CisterNino »

Ciao Studioeco.
Premesso, che ho fatto un test e neanche io ho riscontrato il tuo problema, la soluzione che proponi potrebbe andar bene.

Ad ogni modo, se puoi, ti direi di fare questo test.
Apriti il file \lib\lib.json.php e prenditi la funzione "encode" (riga 238). Commenta le le righe di codice da 359 a 422 e richiamala passandogli in input stringhe accentate. Installala sul tuo server e verifica.

Nel frattempo, facciamo una verifica approfondita se, effettivamente la chiamata this->json->encode($result) in quel si può sostituire senza ulteriori impatti.
I'm Livio, the Two. If you need, you can contact the one.
studioeco
Newbie
Posts: 7
Joined: Mon Feb 19, 2018 6:21 pm

Re: [Bug? Forma 2.4.x] Services_JSON, accenti

Post by studioeco »

Allora, innanzitutto grazie ad entrambi per il supporto.
Ho creato un file chiamandolo test.php e ci ho copiato dentro il seguente contenuto (in sostanza quello che ha detto CisterNino con l'aggiunta della funzione utf82utf16 in modo che funzionansse tutto localmente.

Ho quindi eseguito il file e il risultato è il seguente: Image
Vi incollo qui l'intero file che ho testato

Code: Select all

<?php
function encode($var)
{
	switch (gettype($var)) {
		case 'boolean':
			return $var ? 'true' : 'false';

		case 'NULL':
			return 'null';

		case 'integer':
			return (int) $var;

		case 'double':
		case 'float':
			return (float) $var;

		case 'string':
			// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
			$ascii = '';
			$strlen_var = strlen($var);

		   /*
			* Iterate over every character in the string,
			* escaping with a slash or encoding to UTF-8 where necessary
			*/
			for ($c = 0; $c < $strlen_var; ++$c) {

				$ord_var_c = ord($var{$c});

				switch (true) {
					case $ord_var_c == 0x08:
						$ascii .= '\b';
						break;
					case $ord_var_c == 0x09:
						$ascii .= '\t';
						break;
					case $ord_var_c == 0x0A:
						$ascii .= '\n';
						break;
					case $ord_var_c == 0x0C:
						$ascii .= '\f';
						break;
					case $ord_var_c == 0x0D:
						$ascii .= '\r';
						break;

					case $ord_var_c == 0x22:
					case $ord_var_c == 0x2F:
					case $ord_var_c == 0x5C:
						// double quote, slash, slosh
						$ascii .= '\\'.$var{$c};
						break;

					case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
						// characters U-00000000 - U-0000007F (same as ASCII)
						$ascii .= $var{$c};
						break;

					case (($ord_var_c & 0xE0) == 0xC0):
						// characters U-00000080 - U-000007FF, mask 110XXXXX
						// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
						$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
						$c += 1;
						$utf16 = utf82utf16($char);
						$ascii .= sprintf('\u%04s', bin2hex($utf16));
						break;

					case (($ord_var_c & 0xF0) == 0xE0):
						// characters U-00000800 - U-0000FFFF, mask 1110XXXX
						// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
						$char = pack('C*', $ord_var_c,
									 ord($var{$c + 1}),
									 ord($var{$c + 2}));
						$c += 2;
						$utf16 = utf82utf16($char);
						$ascii .= sprintf('\u%04s', bin2hex($utf16));
						break;

					case (($ord_var_c & 0xF8) == 0xF0):
						// characters U-00010000 - U-001FFFFF, mask 11110XXX
						// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
						$char = pack('C*', $ord_var_c,
									 ord($var{$c + 1}),
									 ord($var{$c + 2}),
									 ord($var{$c + 3}));
						$c += 3;
						$utf16 = utf82utf16($char);
						$ascii .= sprintf('\u%04s', bin2hex($utf16));
						break;

					case (($ord_var_c & 0xFC) == 0xF8):
						// characters U-00200000 - U-03FFFFFF, mask 111110XX
						// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
						$char = pack('C*', $ord_var_c,
									 ord($var{$c + 1}),
									 ord($var{$c + 2}),
									 ord($var{$c + 3}),
									 ord($var{$c + 4}));
						$c += 4;
						$utf16 = utf82utf16($char);
						$ascii .= sprintf('\u%04s', bin2hex($utf16));
						break;

					case (($ord_var_c & 0xFE) == 0xFC):
						// characters U-04000000 - U-7FFFFFFF, mask 1111110X
						// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
						$char = pack('C*', $ord_var_c,
									 ord($var{$c + 1}),
									 ord($var{$c + 2}),
									 ord($var{$c + 3}),
									 ord($var{$c + 4}),
									 ord($var{$c + 5}));
						$c += 5;
						$utf16 = utf82utf16($char);
						$ascii .= sprintf('\u%04s', bin2hex($utf16));
						break;
				}
			}

			return '"'.$ascii.'"';

		
	}
}

function utf82utf16($utf8)
{
	// oh please oh please oh please oh please oh please
	if(function_exists('mb_convert_encoding')) {
		return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
	}

	switch(strlen($utf8)) {
		case 1:
			// this case should never be reached, because we are in ASCII range
			// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
			return $utf8;

		case 2:
			// return a UTF-16 character from a 2-byte UTF-8 char
			// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
			return chr(0x07 & (ord($utf8{0}) >> 2))
				 . chr((0xC0 & (ord($utf8{0}) << 6))
					 | (0x3F & ord($utf8{1})));

		case 3:
			// return a UTF-16 character from a 3-byte UTF-8 char
			// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
			return chr((0xF0 & (ord($utf8{0}) << 4))
					 | (0x0F & (ord($utf8{1}) >> 2)))
				 . chr((0xC0 & (ord($utf8{1}) << 6))
					 | (0x7F & ord($utf8{2})));
	}

	// ignoring UTF-32 for now, sorry
	return '';
}

$test = 'àèìòùèé';
echo("The text before was: '$test'\n\n");
$converted = encode($test);
echo("The converted test is: '$converted'\n\n");
Per chiarezza la versione del server è un Centos 8 (appena scaricato usando vagrant) sul quale ho installato l'ultimo nginx e i pacchetti php70 remi sono i seguenti

Code: Select all

php70-php-pdo-7.0.33-21.el8.remi.x86_64
php70-php-xml-7.0.33-21.el8.remi.x86_64
php70-php-mcrypt-7.0.33-21.el8.remi.x86_64
php70-php-cli-7.0.33-21.el8.remi.x86_64
php70-php-fpm-7.0.33-21.el8.remi.x86_64
php70-php-mysqlnd-7.0.33-21.el8.remi.x86_64
php70-php-mbstring-7.0.33-21.el8.remi.x86_64
php70-php-pecl-zip-1.18.2-1.el8.remi.x86_64
php70-runtime-2.0-1.el8.remi.x86_64
php70-php-common-7.0.33-21.el8.remi.x86_64
php70-2.0-1.el8.remi.x86_64
php70-php-pecl-mysql-1.0.0-0.20.20180226.647c933.el8.remi.x86_64
php70-php-json-7.0.33-21.el8.remi.x86_64
Grazie ancora.
Attachments
Annotazione 2020-06-11 223415.jpg
User avatar
CisterNino
FormaLms User
Posts: 72
Joined: Mon May 06, 2013 2:59 pm

Re: [Bug? Forma 2.4.x] Services_JSON, accenti

Post by CisterNino »

Ok. Il test è quello. Però la pagina test.php, dovresti caricarla sullo stesso server sul quale hai il problema e richiamarla dal web. Il risultato atteso, stando quello che hai scritto nei tuoi post, dovrebbe essere le lettere accentate non scritte correttamente.
I'm Livio, the Two. If you need, you can contact the one.
studioeco
Newbie
Posts: 7
Joined: Mon Feb 19, 2018 6:21 pm

Re: [Bug? Forma 2.4.x] Services_JSON, accenti

Post by studioeco »

CisterNino wrote: Fri Jun 12, 2020 8:25 am Ok. Il test è quello. Però la pagina test.php, dovresti caricarla sullo stesso server sul quale hai il problema e richiamarla dal web. Il risultato atteso, stando quello che hai scritto nei tuoi post, dovrebbe essere le lettere accentate non scritte correttamente.
Ok ho scoperto l'arcano :-)

Per farla breve l'installazione di php-mbstring mancava o era fallata (che casualità) su entrambe le macchine su cui non funzionava la funzione.

Di fatto però il problema (che ripeto si rolve installando php-mbstring) sposta l'attenzione sulla funzione utf82utf16 del file lib.json.php.
In sostanza nelle prime 3 righe di quella funzione si controlla che esista mb_convert_encoding (che è una funzione che si trova nel mod mbstring appunto) per poi usarla. Il problema è quando questa funzione non esiste, perchè a quel punto si oltrepassano le prime 3 righe di codice e le seguenti generano dei caratteri non validi.

Direi che forse conviene lanciare un'eccezione a quel punto così da evitare ogni problema al riguardo.

Grazie di nuovo a tutti per il supporto.
Post Reply