Created
June 29, 2025 12:03
-
-
Save jes/330031f6c28331923a90df96f2555eee to your computer and use it in GitHub Desktop.
Max's Imagebin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* ChangeLog: | |
21-08-2023: | |
- added password because someone uploaded a topless image | |
20-11-2020: | |
- make thumbnails 600px instead of 200px | |
- use imagemagick to do resizing instead of PHP GD | |
- change default host from img.jes.xxx to img.incoherency.co.uk | |
13-12-2018: | |
- host bootstrap locally instead of using maxcdn | |
11-12-2018: | |
- use exiftool to strip exif data | |
06-10-2017: | |
- fix XSS in page param (discovered by cht) | |
16-12-2014: | |
- make buttons bigger and increase spacing | |
21-11-2014: | |
- Various changes to make it work after move to new VM | |
- bootstrap ui (bad) | |
31-01-2012: | |
- Redirect to the image instead of giving a link after an image is uploaded (idea from Mateusz Kowalczyk) | |
06-12-2011: | |
- Add an index.php in images/original/ to redirect people to /imagebin/ | |
16-11-2011: | |
- Fix check that file is actually an image (which only worked by accident) | |
04-09-2011: | |
- Removed "Display a maximum of 9 images per page" | |
- changed paths to be "/img/N" instead of "/img/N.ext" (see /etc/lighttpd/choose-ext.lua) | |
16-01-2011: | |
- changed "Upload Picture!" to "Upload image" | |
24-08-2010: | |
- removed all trailing whitespace | |
- switched to more consistent css | |
- cleaned up url's with index.php in | |
- added Max's name | |
29-07-2010: | |
- fixed another link to /images/original/ | |
29-05-2010: | |
- images/original/ in links goes to /img/ now (with alias configured in /etc/lighttpd/lighttpd.conf) | |
- Now computes the correct hostname instead of assuming aw.eso.me.uk | |
- Makes sure thumbnails fit inside 200x200 pixels | |
- Uses 'sort' instead of 'ls -t' so that files are listed in the right order even if timestamps become wrong | |
- No longer uses separate thumbsarray and orginalarray because this can get confused if there is an extra thumb or extra original | |
- Image thumbnails are now the same filetype as the originals | |
- Now limited to 100 uploads per day and 5MB per image (resets upoad_count to 0 at midnight, see /etc/crontab) | |
- mad css skillz | |
- alpha channels in png thumbnails | |
*/ | |
/* compute correct hostname for this client */ | |
if(isset($_SERVER['HTTP_HOST'])) { | |
$host = $_SERVER['HTTP_HOST']; | |
} else { | |
$host = "img.incoherency.co.uk"; | |
} | |
/* find number of images uploaded today */ | |
$upload_count = (int)file_get_contents("upload_count"); | |
$err_msg = ""; | |
if (isset($_FILES['upload']['tmp_name']) && $_FILES['upload']['size'] > 0){ | |
if ($_POST['password'] != 'password') { | |
$err_msg .= "<b>Incorrect password.</b><br>"; | |
} else if($upload_count >= 100) { | |
$err_msg .= "<b>No more uploads allowed today. I apologise for the inconvenience.</b><br>"; | |
} else if($_FILES['upload']['size'] > 16000000) { | |
$err_msg .= "<b>Sorry, maximum size of 16MB per image.</b><br>"; | |
} else { | |
ob_start(); | |
passthru("ls images/original | sort -n | tail -n1"); | |
$lastfilename = ob_get_contents(); | |
ob_end_clean(); | |
$lastnum = explode(".", $lastfilename); | |
$curnum = $lastnum[0] + 1; | |
$filenameparts = explode(".", $_FILES['upload']['name']); | |
$imgsize = getimagesize($_FILES['upload']['tmp_name']); | |
if(!$imgsize) { | |
$err_msg .= "<b>Sorry, images only.</b><br>"; | |
} else { | |
$shortfilename = sprintf("%s%s", $curnum, image_type_to_extension($imgsize[2])); | |
$newfilename = "images/original/$shortfilename"; | |
$thumbfilename = "images/thumbs/$shortfilename"; | |
move_uploaded_file($_FILES['upload']['tmp_name'], $newfilename); | |
ob_start(); | |
passthru("exiftool -overwrite_original -all= -tagsFromFile @ -orientation $newfilename"); | |
passthru("convert $newfilename -geometry 600x600 $thumbfilename"); | |
ob_end_clean(); | |
/* increment the upload count */ | |
$upload_count += 1; | |
$fp = fopen("upload_count", "w"); | |
fwrite($fp, $upload_count . "\n"); | |
fclose($fp); | |
header("Location: /$curnum"); | |
exit(); | |
} | |
} | |
} | |
?> | |
<!doctype html> | |
<head> | |
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> | |
<title>imagebin</title> | |
<link rel="stylesheet" type="text/css" href="bootstrap.min.css"> | |
<style type="text/css"> | |
.btn-file { | |
position: relative; | |
overflow: hidden; | |
} | |
.btn-file input[type=file] { | |
position: absolute; | |
top: 0; | |
right: 0; | |
min-width: 100%; | |
min-height: 100%; | |
font-size: 100px; | |
text-align: right; | |
filter: alpha(opacity=0); | |
opacity: 0; | |
outline: none; | |
background: white; | |
cursor: inherit; | |
display: block; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row"> | |
<h1>imagebin</h1> | |
<br><br><br> | |
<form action="/" enctype="multipart/form-data" method="post"> | |
Select an image:<br><input type="file" name="upload" style="font-size: 2em" id="selectimg"> | |
<br><br> | |
<input name="password" type="password" placeholder="Password"> | |
<br><br> | |
<button class="btn btn-lg btn-primary" style="width:100%" type="submit">Upload</button> | |
<br><br><br> | |
<?php | |
//if(isset($err_msg)) { | |
echo $err_msg; | |
//} | |
echo("</div>"); | |
echo('<div class="row">'); | |
if(!isset($_GET['thumbs']) && !isset($_GET['page'])){ | |
echo('<a href="/?thumbs=1">Show thumbnails.</a>'); | |
} | |
else{ | |
$curpage = max((int)$_GET['page'], 1); | |
/* $thumbsarray = array_merge(array_diff(scandir("images/thumbs"), array('.', '..'))); */ | |
ob_start(); | |
passthru("ls images/thumbs/ | sort -nr"); | |
$thumbslist = ob_get_contents(); | |
ob_end_clean(); | |
$thumbsarray = explode("\n", $thumbslist); | |
$numthumbs = sizeof($thumbsarray) - 1; | |
$thumbsperpage = 16; | |
$thumbsperrow = 4; | |
/* $originalarray = array_merge(array_diff(scandir("images/original"), array('.', '..'))); */ | |
$tdname = array("odd", "even"); | |
$tdstate = 0; | |
$curpage = max((int)$_GET['page'], 1); | |
$maxpage = ceil($numthumbs / $thumbsperpage); | |
$n = $thumbsperpage * ($curpage - 1); | |
$total = 0; | |
echo( 'Page ' . $curpage . ' of ' . $maxpage . ' - '); | |
if($curpage > 1){ | |
echo('<a href="/?page=1">First Page</a>  '); | |
echo('<a href="/?page=' . ($curpage-1) . '">Previous Page</a>  '); | |
} | |
if($curpage < $maxpage){ | |
echo('<a href="/?page=' . ($curpage+1) . '">Next Page</a>  '); | |
echo('<a href="/?page=' . $maxpage . '">Final Page</a><br><br>'); | |
} | |
echo('<table style="width: auto; margin: auto">'); | |
while(($n < $numthumbs) && ($total < $thumbsperpage)){ | |
echo('<tr>'); | |
while($i < $thumbsperrow && $n < $numthumbs){ | |
$parts = explode(".", $thumbsarray[$n]); | |
$number = $parts[0]; | |
echo( '<td class="' . $tdname[$tdstate] . '"><a href="/' . $number . '"><img style="max-width:200px;max-height:200px" src="images/thumbs/' . $thumbsarray[$n] .'"></a></td>'); | |
$total++; | |
$i++; | |
$n++; | |
$tdstate = !$tdstate; | |
} | |
echo('</tr>'); | |
$i = 0; | |
} | |
echo( '</table><br>Page ' . $curpage . ' of ' . $maxpage . ' - '); | |
if($curpage > 1){ | |
echo('<a href="/?page=1">First Page</a>  '); | |
echo('<a href="/?page=' . ($curpage-1) . '">Previous Page</a>  '); | |
} | |
if($curpage < $maxpage){ | |
echo('<a href="/?page=' . ($curpage+1) . '">Next Page</a>  '); | |
echo('<a href="/?page=' . $maxpage . '">Final Page</a>  '); | |
} | |
} | |
if($upload_count == 1) { $plural = " image "; } | |
else { $plural = " images "; } | |
echo('<br><i>' . $upload_count . $plural . 'uploaded today.</i>'); | |
?> | |
<br><br> | |
imagebin by Maximilian of #maximilian (irc.freenode.net) | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment