BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. #declare(strict_types=1);
  3. if (!check_perms('site_proxy_images')) {
  4. img_error('forbidden');
  5. }
  6. $URL = isset($_GET['i']) ? htmlspecialchars_decode($_GET['i']) : null;
  7. if (!extension_loaded('openssl') && strtoupper($URL[4]) === 'S') {
  8. img_error('badprotocol');
  9. }
  10. /*
  11. if (!(preg_match('/^'.IMAGE_REGEX.'/is', $URL, $Matches) || preg_match('/^'.VIDEO_REGEX.'/is', $URL, $Matches))) {
  12. img_error('invalid');
  13. }
  14. */
  15. if (isset($_GET['c'])) {
  16. list($Data, $FileType) = $Cache->get_value('image_cache_'.md5($URL));
  17. $Cached = true;
  18. }
  19. if (!isset($Data) || !$Data) {
  20. $Cached = false;
  21. $Data = @file_get_contents($URL, 0, stream_context_create(array('http' => array('timeout' => 15), 'ssl' => array('verify_peer' => false))));
  22. if (!$Data || empty($Data)) {
  23. img_error('timeout');
  24. }
  25. $FileType = image_type($Data);
  26. if ($FileType && function_exists("imagecreatefrom$FileType")) {
  27. $Image = imagecreatefromstring($Data);
  28. if (invisible($Image)) {
  29. img_error('invisible');
  30. }
  31. if (verysmall($Image)) {
  32. img_error('small');
  33. }
  34. }
  35. if (isset($_GET['c']) && strlen($Data) < 524288 && substr($Data, 0, 1) != '<') {
  36. $Cache->cache_value('image_cache_'.md5($URL), array($Data, $FileType), 3600 * 24 * 7);
  37. }
  38. }
  39. // Reset avatar, add mod note
  40. function reset_image($UserID, $Type, $AdminComment, $PrivMessage)
  41. {
  42. $ENV = ENV::go();
  43. if ($Type === 'avatar') {
  44. $CacheKey = "user_info_$UserID";
  45. $DBTable = 'users_info';
  46. $DBColumn = 'Avatar';
  47. $PMSubject = 'Your avatar has been automatically reset';
  48. } elseif ($Type === 'avatar2') {
  49. $CacheKey = "donor_info_$UserID";
  50. $DBTable = 'donor_rewards';
  51. $DBColumn = 'SecondAvatar';
  52. $PMSubject = 'Your second avatar has been automatically reset';
  53. } elseif ($Type === 'donoricon') {
  54. $CacheKey = "donor_info_$UserID";
  55. $DBTable = 'donor_rewards';
  56. $DBColumn = 'CustomIcon';
  57. $PMSubject = 'Your donor icon has been automatically reset';
  58. }
  59. $UserInfo = G::$Cache->get_value($CacheKey, true);
  60. if ($UserInfo !== false) {
  61. if ($UserInfo[$DBColumn] === '') {
  62. // This image has already been reset
  63. return;
  64. }
  65. $UserInfo[$DBColumn] = '';
  66. G::$Cache->cache_value($CacheKey, $UserInfo, 2592000); // cache for 30 days
  67. }
  68. // Reset the avatar or donor icon URL
  69. G::$DB->query("
  70. UPDATE $DBTable
  71. SET $DBColumn = ''
  72. WHERE UserID = '$UserID'");
  73. // Write comment to staff notes
  74. G::$DB->query("
  75. UPDATE users_info
  76. SET AdminComment = CONCAT('".sqltime().' - '.db_string($AdminComment)."\n\n', AdminComment)
  77. WHERE UserID = '$UserID'");
  78. // Clear cache keys
  79. G::$Cache->delete_value($CacheKey);
  80. Misc::send_pm($UserID, 0, $PMSubject, $PrivMessage);
  81. }
  82. // Enforce avatar rules
  83. if (isset($_GET['type']) && isset($_GET['userid'])) {
  84. $ValidTypes = array('avatar', 'avatar2', 'donoricon');
  85. if (!is_number($_GET['userid']) || !in_array($_GET['type'], $ValidTypes)) {
  86. error();
  87. }
  88. $UserID = $_GET['userid'];
  89. $Type = $_GET['type'];
  90. if ($Type === 'avatar' || $Type === 'avatar2') {
  91. $MaxFileSize = 512 * 1024; // 512 kiB
  92. $MaxImageHeight = 600; // pixels
  93. $TypeName = $Type === 'avatar' ? 'avatar' : 'second avatar';
  94. } elseif ($Type === 'donoricon') {
  95. $MaxFileSize = 128 * 1024; // 128 kiB
  96. $MaxImageHeight = 100; // pixels
  97. $TypeName = 'donor icon';
  98. }
  99. $Height = image_height($FileType, $Data);
  100. if (strlen($Data) > $MaxFileSize || $Height > $MaxImageHeight) {
  101. // Sometimes the cached image we have isn't the actual image
  102. if ($Cached) {
  103. $Data2 = file_get_contents($URL, 0, stream_context_create(array('http' => array('timeout' => 60), 'ssl' => array('verify_peer' => false))));
  104. } else {
  105. $Data2 = $Data;
  106. }
  107. if ((strlen($Data2) > $MaxFileSize || image_height($FileType, $Data2) > $MaxImageHeight) && $UserID !== 1 && $UserID !== 2) {
  108. require_once SERVER_ROOT.'/classes/mysql.class.php';
  109. require_once SERVER_ROOT.'/classes/time.class.php';
  110. $DBURL = db_string($URL);
  111. $AdminComment = ucfirst($TypeName)." reset automatically (Size: ".number_format((strlen($Data)) / 1024)." kB, Height: ".$Height."px). Used to be $DBURL";
  112. $PrivMessage = "$ENV->SITE_NAME has the following requirements for {$TypeName}s:\n\n".
  113. "[b]".ucfirst($TypeName)."s must not exceed ".($MaxFileSize / 1024)." kB or be vertically longer than {$MaxImageHeight}px.[/b]\n\n".
  114. "Your $TypeName at $DBURL has been found to exceed these rules. As such, it has been automatically reset. You are welcome to reinstate your $TypeName once it has been resized down to an acceptable size.";
  115. reset_image($UserID, $Type, $AdminComment, $PrivMessage);
  116. }
  117. }
  118. }
  119. if (!isset($FileType)) {
  120. img_error('timeout');
  121. }
  122. if ($FileType === 'webm') {
  123. header("Content-type: video/$FileType");
  124. } else {
  125. header("Content-type: image/$FileType");
  126. }
  127. echo $Data;