Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: extreme69 en 9 Julio 2013, 20:39 pm



Título: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: extreme69 en 9 Julio 2013, 20:39 pm
Tengo un problema...

El usuario tiene un archivo .GIF y como mi web no se lo deja subir porque sólo acepta imágenes .PNG, ¿qué hace el usuario? renombra la extensión. Esto me trae complicaciones, ya que se tranca el código y me da errores.

La pregunta es... ¿hay manera de chequear que el archivo que está subiendo el usuario realmente sea .PNG? leyendo los headers de los archivos o algo así?

La misma pregunta va para chequear otros formatos de imágenes como .GIF y .JPG.

Estoy googleando hace hoooooooras, no encuentro nada, denme una pista, algo, por favor.


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: engel lex en 9 Julio 2013, 20:55 pm
te recomiendo 2 paginas para buscar eso... se llaman google y wikipedia... te dejo los links de wikipedia para que revises

http://es.wikipedia.org/wiki/Portable_Network_Graphics (http://es.wikipedia.org/wiki/Portable_Network_Graphics)

Citar
Detalles técnicos
Un archivo PNG empieza con una firma de 8 bytes, los valores en hexadecimal son: 89 50 4E 47 0D 0A 1A 0A, los valores decimales son: 137 80 78 71 13 10 26 10; cada valor está ahí por una razón específica.

http://en.wikipedia.org/wiki/JPEG (http://en.wikipedia.org/wiki/JPEG)
Citar
A JPEG image consists of a sequence of segments, each beginning with a marker, each of which begins with a 0xFF byte followed by a byte indicating what kind of marker it is. Some markers consist of just those two bytes; others are followed by two bytes indicating the length of marker-specific payload data that follows. (The length includes the two bytes for the length, but not the two bytes for the marker.) Some markers are followed by entropy-coded data; the length of such a marker does not include the entropy-coded data. Note that consecutive 0xFF bytes are used as fill bytes for padding purposes, although this fill byte padding should only ever take place for markers immediately following entropy-coded scan data (see JPEG specification section B.1.1.2 and E.1.2 for details; specifically "In all cases where markers are appended after the compressed data, optional 0xFF fill bytes may precede the marker").

http://en.wikipedia.org/wiki/Graphics_Interchange_Format (http://en.wikipedia.org/wiki/Graphics_Interchange_Format)
Citar
GIF files start with a fixed-length header ("GIF87a" or "GIF89a") giving the version, followed by a fixed-length Logical Screen Descriptor giving the size and other characteristics of the logical screen. The screen descriptor may also specify the presence and size of a Global Color Table, which follows next if present.


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: 1mpuls0 en 9 Julio 2013, 20:59 pm
No estoy seguro si con el MIME se puede hacer algo al respecto.



Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: extreme69 en 10 Julio 2013, 09:43 am
te recomiendo 2 paginas para buscar eso... se llaman google y wikipedia... te dejo los links de wikipedia para que revises

http://es.wikipedia.org/wiki/Portable_Network_Graphics (http://es.wikipedia.org/wiki/Portable_Network_Graphics)

http://en.wikipedia.org/wiki/JPEG (http://en.wikipedia.org/wiki/JPEG)
http://en.wikipedia.org/wiki/Graphics_Interchange_Format (http://en.wikipedia.org/wiki/Graphics_Interchange_Format)

Gracias por la inútil información que ya tenía.

Voy a probar con exif_read_data para los JPG, aunque esto no me alienta mucho:

EXIF headers tend to be present in JPEG/TIFF images generated by digital cameras, but unfortunately each digital camera maker has a different idea of how to actually tag their images, so you can't always rely on a specific Exif header being present.


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: extreme69 en 10 Julio 2013, 09:52 am
No estoy seguro si con el MIME se puede hacer algo al respecto.



Mmmmm, voy a probar también con mime_content_type


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: engel lex en 10 Julio 2013, 09:55 am
el mime no te sirve...

no es inutil... agarras el archivo lo subes, lees los primeros bytes y si coinciden con los bytes según el mime eso son, no hay que darle muchas vueltas... la informacion exif no es obligatoria así que no lo vas a conseguir en todos los archivos de esos formatos...


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: extreme69 en 10 Julio 2013, 10:09 am
el mime no te sirve...

no es inutil... agarras el archivo lo subes, lees los primeros bytes y si coinciden con los bytes según el mime eso son, no hay que darle muchas vueltas... la informacion exif no es obligatoria así que no lo vas a conseguir en todos los archivos de esos formatos...

Ya lo intenté, pero si probás por tus medios te das cuenta que eso sólo funciona con PNG's, bueno, en realidad probé con PNG y JPG, con GIF todavía no, dando como resultado que sólo me funciona para PNG's, los JPG no tienen los primeros bytes iguales, dependen de otros factores que desconozco.

Dejo link de un código que encontré para los PNG por si alguien estaba buscando esto:

http://codeaid.net/php/check-if-the-file-is-a-png-image-file-by-reading-its-signature


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: engel lex en 10 Julio 2013, 17:07 pm
para que no digan que no ayudo con códigos...

se puede resumir mucho está hecho para ser leído...

Código
  1. $archivo = "a1.jpg";
  2. $f = fopen($archivo,"rb");
  3. $largo = filesize ($archivo);
  4.  
  5. $debe_tener[] = hexdec ("ff");//inicia
  6. $debe_tener[] = hexdec ("d8");
  7. $debe_tener[] = hexdec ("ff");//finaliza
  8. $debe_tener[] = hexdec ("d9");
  9.  
  10. $contenido[] = ord(fread ($f , 1));
  11. $contenido[] = ord(fread ($f , 1));
  12. fseek($f, $largo-2);
  13. $contenido[] = ord(fread ($f , 1));
  14. $contenido[] = ord(fread ($f , 1));
  15. fclose($f);
  16.  
  17. $es_valido_jpg=true;
  18. for($i=0;$i<count($contenido);$i++) $es_valido_jpg &= $debe_tener[$i]==$contenido[$i];
  19.  
  20. echo "valido jpg = ";
  21. var_dump($es_valido_jpg);
  22. var_dump($contenido);
  23. var_dump($debe_tener);
  24. ///////////////////////////////////////////////////////
  25. unset ($debe_tener);
  26. unset ($contenido);
  27.  
  28. $archivo = "a2.png";
  29. $f = fopen($archivo,"rb");
  30. $largo = filesize ($archivo);
  31.  
  32.  
  33. $debe_tener[] = hexdec ("89");
  34. $debe_tener[] = hexdec ("50");
  35. $debe_tener[] = hexdec ("4e");
  36. $debe_tener[] = hexdec ("47");
  37. $debe_tener[] = hexdec ("0d");
  38. $debe_tener[] = hexdec ("0a");
  39. $debe_tener[] = hexdec ("1a");
  40. $debe_tener[] = hexdec ("0a");
  41.  
  42. for($i=0;$i<count($debe_tener);$i++)
  43. $contenido[] = ord(fread ($f , 1));
  44. fclose($f);
  45.  
  46. $es_valido_png=true;
  47. for($i=0;$i<count($contenido);$i++) $es_valido_png &= $debe_tener[$i]==$contenido[$i];
  48. echo "valido png = ";
  49. var_dump($es_valido_png);
  50. var_dump($contenido);
  51. var_dump($debe_tener);
  52.  
  53. ///////////////////////////////////////////////////////
  54. unset ($debe_tener);
  55. unset ($contenido);
  56.  
  57. $archivo = "a3.gif";
  58. $f = fopen($archivo,"rb");
  59. $largo = filesize ($archivo);
  60.  
  61.  
  62. $debe_tener[] = ord ("G");
  63. $debe_tener[] = ord ("I");
  64. $debe_tener[] = ord ("F");
  65. $debe_tener[] = ord ("8");
  66. $debe_tener[] = ord ("9");
  67. $debe_tener[] = ord ("a");
  68.  
  69.  
  70. for($i=0;$i<count($debe_tener);$i++)
  71. $contenido[] = ord(fread ($f , 1));
  72. fclose($f);
  73.  
  74. $es_valido_gif89a=true;
  75. for($i=0;$i<count($contenido);$i++) $es_valido_gif89a &= $debe_tener[$i]==$contenido[$i];
  76.  
  77. echo "valido gif89a = ";
  78. var_dump($es_valido_gif89a);
  79.  
  80. $debe_tener[4] = ord ("7");
  81. $es_valido_gif87a=true;
  82. for($i=0;$i<count($contenido);$i++) $es_valido_gif87a &= $debe_tener[$i]==$contenido[$i];
  83.  
  84. echo "valido gif87a = ";
  85. var_dump($es_valido_gif87a);
  86.  
  87. $debe_tener[4] = $es_valido_gif89a? ord("9"):ord("7");
  88.  
  89. $es_valido_gif=$es_valido_gif87a||$es_valido_gif89a;
  90.  
  91. echo "valido gif = ";
  92.  
  93. var_dump($es_valido_gif);
  94. var_dump($contenido);
  95. var_dump($debe_tener);

Citar
Gracias por la inútil información que ya tenía.

Citar
JPEG
Syntax and structure
Start Of Image 0xFF, 0xD8   
End Of Image 0xFF, 0xD9

Citar
GIF
File format
GIF files start with a fixed-length header ("GIF87a" or "GIF89a")

Citar
PNG
Detalles técnicos
Un archivo PNG empieza con una firma de 8 bytes, los valores en hexadecimal son: 89 50 4E 47 0D 0A 1A 0A

NO es inútil ahí está todo solo con esa info hice eso...

Citar
Ya lo intenté, pero si probás por tus medios te das cuenta que eso sólo funciona con PNG's, bueno, en realidad probé con PNG y JPG, con GIF todavía no, dando como resultado que sólo me funciona para PNG's, los JPG no tienen los primeros bytes iguales, dependen de otros factores que desconozco.

ni leíste lo que decía en wiki -.-


Título: Re: Chequear si un archivo .PNG es realmente un .PNG
Publicado por: extreme69 en 10 Julio 2013, 17:24 pm
Pah, te la jugaste!!!

No era mi intención tampoco que me pases códigos, me gusta ir aprendiendo en el camino.

Ahora me pongo a revisarlo bien y a probarlo.

Gracias ;-)