PHP Filopplasting - feil med filtype

kek91

Webutvikler
Heisann!

Jeg har fått et litt underlig problem som jeg trenger litt ekspert hjelp til.

Det gjelder da opplasting av bilde.

Her er følgende kodesnutt jeg bruker:
PHP:
if (($_FILES["profpic"]["type"] != "image/gif")
or ($_FILES["profpic"]["type"] != "image/jpeg")
or ($_FILES["profpic"]["type"] != "image/pjpeg")) { 
    echo "The file you tried to upload is not a valid .JPG or .GIF format. Please try again.";
}
Og selv om jeg laster opp riktig filtype så får jeg alltid denne fordømrade feilmeldingen.

Jeg har prøvd å dobbeltsjekke med å skrive:
PHP:
echo $_FILES["profpic"]["type"];
og da får jeg som forventet image/gif når jeg laster opp gif bilde.
Prøvde også png bilde for gøy, og da får jeg image/png, og det er jo helt korrekt.
Så tydeligvis får jeg riktig fil endelse, men hvorfor i huleste heita slipper ikke gif bildet gjennom?

Den eneste løsningen jeg kan bruke er å gjøre følgende:
PHP:
$ext = pathinfo($_FILES["profpic"]["name"], PATHINFO_EXTENSION);
if (($ext != "gif")
or ($ext != "jpeg")
or ($ext != "pjpeg")) {
	echo "The file you tried to upload is not a valid .JPG or .GIF format. Please try again.";
}
Men jeg vet ikke om dette er like sikkert?? Derfor spør jeg dere folkens om hva som kan være feil med den første kodesnutten. :)

Takker for alle svar!

EDIT!
Jeg ser nå at INGEN av kodesnuttene fungerer!
Men hvis jeg prøver å bare teste 1 filendelse så går det.

For eksempel:
PHP:
$ext = pathinfo($_FILES["profpic"]["name"], PATHINFO_EXTENSION);
if ($ext != "gif") {
	echo "The file you tried to upload is not a valid .JPG or .GIF format. Please try again.";
}
Det fungerer helt fint. Så da er det vel heller oppsettet på spørringen min som er feil.
Det var litt merkelig mtp at de har gjort det likt her:
PHP File Upload
PHP:
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

    if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $_FILES["file"]["name"]);
      echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
      }
    }
  }
else
  {
  echo "Invalid file";
  }
?>
 
Sist redigert:

Nutz

Med lem
:cool: Ikke sikker på om det bare er en skriveleif fra deg..

"og da får jeg som forventet images/gif når jeg laster opp gif bilde."

Men dette er jo ikke likt det du tester mot..
PHP:
 if ($_FILES["profpic"]["type"] != "image/gif")

"image/gif" er ikke lik "images/gif"
 

kek91

Webutvikler
Hei Nutz!

Tusen takk for hurtig svar, men det var dessverre bare en skriveleif fra min side.
Jeg mente: "og da får jeg som forventet image/gif når jeg laster opp gif bilde"

Men, jeg testet en litt ny kode med en "and" på slutten:
PHP:
if ((($_FILES["profpic"]["type"] != "image/gif")
or ($_FILES["profpic"]["type"] != "image/jpeg")
or ($_FILES["profpic"]["type"] != "image/pjpeg"))
and ($_FILES["profpic"]["size"] > 20000)) {
    echo "Picture has illegal file format or filesize is too big.";
}
Denne koden fungerer helt fint.

Alt som er forskjellig fra denne kodesnutten og den originale er at jeg plusset på en "and........" på slutten. Er det ikke mulig å bare kjøre en if....or....or... uten en and på slutten?

Dette var nytt for meg i såfall, med mindre jeg har enda en slurvefeil et eller annet sted.
 

Nutz

Med lem
Ser ut som "vi" har rotet oss inn i en test der alle må være "sanne/usanne" for at uttrykket skal gå igjennom.. :) -Hodet funker ikke helt enda.. Klarer ikke å se den logiske "fella".

Denne skal gå igjennom

PHP:
if (($_FILES["profpic"]["type"] == "image/gif") 
or ($_FILES["profpic"]["type"] == "image/jpeg") 
or ($_FILES["profpic"]["type"] == "image/pjpeg"))
    {    
     echo "Gyldig format</br>";
     } 
     else
    {
     echo "Ugyldig format";
     }
?>
 

amaheath

Medlem
Den logiske feilen er fordi du tester:

Hvis filtype er ulik GIF, eller filtype er ulik JPEG, eller filtype er ulik PJPEG så gir du feilmelding.

Så: hvis filypen er korrekt, f.eks. GIF, så er den jo ulik JPG og du får feilmelding.

Så derfor er snutten til nutz riktig. :)

Hadde også virket hvis du hadde brukt AND i stedet for OR i første eksempelet.
 

kek91

Webutvikler
Aha!
Tusen takk for hjelp begge to. Begge tipsa fungerer :)

amaheath, jeg tenkte den tanken tusen ganger, men i mitt hode hørtes det mer logisk ut å spørre "hvis den er sann, ELLER den, ELLER den" istedenfor "hvis den er sann, OG den, OG den" fordi da må jo alle 3 være sanne? Jeg ser nå at jeg har tatt feil, men det hørtes bedre ut i mitt hode, hehe :)

Takk for hjelp folkens!
 

xdex

Medlem
Dersom du bruker denne metoden, kan vi enkelte laste opp PHP-Filer/Shell til domenet ditt. Det du gjør er å sjekke verdier opp mot $_FILES noe som ikke vil fungere, dersom du er usikker på hvorfor vil jeg anbefale at du leser litt mer om hvordan dette fungerer.

I praksis kan man laste opp hvilken som helst fil. Man laster opp heisann.php og forteller browseren at dette er "image/png" da vil også serveren din godta filene som blir lastet opp. Og sjekke om det er bilder som blir lastet opp ved bruk av $_FILES er helt feil, dette er sikkerhetsproblem, hvem som helst kan få tilgang til hele serveren ved å laste opp eget shell etc.
 

xdex

Medlem
Her har du ett eksempel jeg lagde, ikke ferdig testet men skal fungere helt greit, du slipper også å tenke på $_FILES problematikken.

PHP:
<?php

// Find image extension (.jpg/.png) etc
function getExtension($str) {
    $i = strrpos($str,".");
    if (!$i) { return ""; }
    $l = strlen($str) - $i;
    $ext = substr($str,$i+1,$l);
    return $ext;
}

// Check the filename
$fileName = 'ImaGe.jPg'; // $_FILES['Filedata']['name'];

// Get extension
$extension = getExtension($fileName);
$extension = strtolower($extension);

// Array with allowed types
$imageType = array('jpg','png','gif','jpeg');

// Check extension

if(!in_array($extension,$imageType)) {
    die('Dette er ikke ett bilde!');
}

// Final check (check if the uploaded file is an image)
$imageSize = @getimagesize($image);
if(!is_numeric($imageSize[0]) && !is_numeric($imageSize[1])){
    die('Dette er ikke ett bilde!');
}

// Validering er fullført, du kan nå flytte bildet hvor du ønsker.

?>

Lykke til!
 

kek91

Webutvikler
Tusen takk Roaa!
Nå gjorde du jo egentlig hjemmeleksa mi, men jeg setter stor pris på det :)

Det jeg lurte litt på var:
if(!is_numeric($imageSize[0]..........................................

Jeg sjekket det på php.net og der sier de følgende:
This optional parameter allows you to extract some extended information from the image file. Currently, this will return the different JPG APP markers as an associative array. Some programs use these APP markers to embed text information in images. A very common one is to embed » IPTC information in the APP13 marker. You can use the iptcparse() function to parse the binary APP13 marker into something readable.
Så, grunnen til at du sjekket både getimagesize[0] og getimagesize[1] istedenfor bare getimagesize er fordi hvis man ikke sjekker begge så er det mulig å skjule kode i ekstra informasjonen som sier at det er et bilde (mens det egentlig er en ondsinnet fil) ?
 

xdex

Medlem
Stemmer :)

Men selv om du har en løsning her, betyr det ikke at man ikke skal lese på det. Det er viktig og forstå hvordan det fungerer og hvorfor man kan laste opp andre filer. Men jeg er sikker på at du kommer deg over denne haugen, så stor er den ikke :rolleyes:
 

Pong

Jeg selger sʇɥƃıluʍop :)
Jeg ville kun holdt meg til GD-funksjoner - filetternavn betyr ikke mye. Så sjekken med getimagesize er egentlig nok i mine øyne.

Etterpå ville jeg konvertert bildet til en standard størrelse. Det ville ødelagt alt av "idioti" folk sender med bildene som feil dimensjon-informasjon, overflows, php-kode inni gifs, og hva de måtte finne på i framtiden.
Jeg går da ut fra at GD-koden ikke går i stykker.
 

kek91

Webutvikler
Stemmer :)

Men selv om du har en løsning her, betyr det ikke at man ikke skal lese på det. Det er viktig og forstå hvordan det fungerer og hvorfor man kan laste opp andre filer. Men jeg er sikker på at du kommer deg over denne haugen, så stor er den ikke :rolleyes:

Nei, så klart :)
Jeg vet jeg har veldig mye å lære, men jeg setter pris på når folk kommer med eksempler, jeg liker å se hvordan andre gjør ting og jeg syntes det blir lettere å lære.

Okay Pong, da vil jeg i hvert fall spare litt kode :)
Foreløpig har jeg skrevet et script som konverterer bilde om til en thumbnail og så lagt det i en ny mappe, men jeg har ikke pleid å konvertere original bilde. Det er nok kanskje noe jeg burde gjøre for å unngå eksemplene du kommer med
 
Topp