403Webshell
Server IP : 188.114.96.3  /  Your IP : 216.73.216.143
Web Server : Apache
System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64
User :  ( 3194769)
PHP Version : 8.5.12
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /test2.famaresto/szukaj/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /test2.famaresto/szukaj/api.php
<?php
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');

/** -------- UTF-8 hardening (żeby json_encode nie wywalał) -------- */
function _is_valid_utf8($s) {
  return is_string($s) && preg_match('//u', $s);
}

function _fix_to_utf8($s) {
  if (!is_string($s)) return $s;
  if ($s === '') return $s;

  // już OK
  if (_is_valid_utf8($s)) return $s;

  // spróbuj typowe PL kodowania nazw plików
  if (function_exists('iconv')) {
    foreach (['Windows-1250', 'CP1250', 'ISO-8859-2'] as $enc) {
      $t = @iconv($enc, 'UTF-8//IGNORE', $s);
      if (is_string($t) && $t !== '' && _is_valid_utf8($t)) return $t;
    }
    // ostatnia deska ratunku: wytnij bajty psujące UTF-8
    $t = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
    if (is_string($t) && $t !== '') return $t;
  }

  // hard fallback: tylko ASCII
  return preg_replace('/[^\x20-\x7E]/', '', $s);
}

function _normalize_for_json($v) {
  if (is_array($v)) {
    $out = [];
    foreach ($v as $k => $val) {
      $nk = _fix_to_utf8((string)$k);
      $out[$nk] = _normalize_for_json($val);
    }
    return $out;
  }
  if (is_string($v)) return _fix_to_utf8($v);
  return $v;
}

function json_out($payload, $status = 200) {
  http_response_code($status);

  $payload = _normalize_for_json($payload);

  $opts = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
  if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) $opts |= JSON_INVALID_UTF8_SUBSTITUTE;

  $json = json_encode($payload, $opts);
  if ($json === false) {
    $msg = function_exists('json_last_error_msg') ? json_last_error_msg() : 'json_encode_failed';
    echo '{"docs":[],"error":"json_encode_failed","msg":"' . addslashes($msg) . '"}';
    exit;
  }

  echo $json;
  exit;
}

/** -------- config + helpers -------- */
function load_config() {
  $file = __DIR__ . '/config.php';
  if (is_file($file)) {
    $cfg = include $file;
    if (is_array($cfg)) return $cfg;
  }
  return [];
}

function detect_base_url($configured) {
  // pozwól jawnie ustawić '' (root)
  if ($configured !== null) {
    $configured = (string)$configured;
    $b = '/' . trim($configured, '/');
    return ($b === '/') ? '' : $b;
  }

  $scriptDir = str_replace('\\', '/', dirname(isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '/szukaj/api.php'));
  $base = preg_replace('~/szukaj$~', '', $scriptDir);
  $base = rtrim((string)$base, '/');
  if ($base === '/' || $base === '') return '';
  return $base;
}

function url_path_from_rel($rel, $baseUrl) {
  // UWAGA: rawurlencode działa na bajtach – to jest OK nawet gdy nazwy plików są "dziwne"
  $parts = explode('/', $rel);
  $enc = [];
  foreach ($parts as $p) $enc[] = rawurlencode($p);
  $path = '/' . implode('/', $enc);
  return ($baseUrl === '') ? $path : ($baseUrl . $path);
}

function human_title_from_filename($filename) {
  $filename = _fix_to_utf8($filename);

  $base = preg_replace('/\.[^.]+$/', '', $filename);
  $base = str_replace(['_','-','.'], ' ', $base);
  $base = preg_replace('/\s+/', ' ', (string)$base);
  $base = trim((string)$base);
  if ($base === '') return $filename;

  $first = strtoupper(substr($base, 0, 1));
  return $first . substr($base, 1);
}

function scan_dir($dir, $root, $baseUrl, $allowedExt, $excludeDirs, $excludeFiles, $overrides, &$docs, &$errors, &$countFiles, $maxFiles) {
  if ($countFiles >= $maxFiles) return;

  $items = @scandir($dir);
  if ($items === false) {
    $errors[] = "Brak dostępu do katalogu: " . $dir;
    return;
  }

  foreach ($items as $name) {
    if ($name === '.' || $name === '..') continue;

    $path = $dir . DIRECTORY_SEPARATOR . $name;

    // omijaj symlinki (często pętle/permission)
    if (@is_link($path)) continue;

    if (@is_dir($path)) {
      if (in_array($name, $excludeDirs, true)) continue;
      if (strlen($name) > 0 && $name[0] === '.') continue; // ukryte

      if (!@is_readable($path)) {
        $errors[] = "Nieczytelny katalog: " . $path;
        continue;
      }

      scan_dir($path, $root, $baseUrl, $allowedExt, $excludeDirs, $excludeFiles, $overrides, $docs, $errors, $countFiles, $maxFiles);
      if ($countFiles >= $maxFiles) return;
      continue;
    }

    if (!@is_file($path)) continue;
    if (in_array($name, $excludeFiles, true)) continue;

    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    if (!in_array($ext, $allowedExt, true)) continue;

    $countFiles++;

    // rel path (bajty zostają, bo URL i tak percent-enc)
    $rootNorm = rtrim(str_replace('\\','/',$root), '/') . '/';
    $absNorm  = str_replace('\\','/',$path);
    $rel = (strpos($absNorm, $rootNorm) === 0) ? substr($absNorm, strlen($rootNorm)) : $absNorm;

    $section = 'Główne';
    $parts = explode('/', $rel);
    if (count($parts) >= 2 && $parts[0] !== '') $section = _fix_to_utf8($parts[0]);

    $title = (isset($overrides[$rel]) && is_string($overrides[$rel]) && $overrides[$rel] !== '')
      ? _fix_to_utf8($overrides[$rel])
      : human_title_from_filename($name);

    $docs[] = [
      'title'   => $title,
      'rel'     => _fix_to_utf8($rel),
      'url'     => url_path_from_rel($rel, $baseUrl),
      'section' => $section,
      'ext'     => $ext,
    ];

    if ($countFiles >= $maxFiles) return;
  }
}

/** -------- main -------- */
$cfg = load_config();
$debug = isset($_GET['debug']) && $_GET['debug'] == '1';

// Domyślnie: katalog strony = parent katalogu "szukaj"
$ROOT = isset($cfg['scan_root']) ? $cfg['scan_root'] : dirname(__DIR__);
$ROOT_REAL = @realpath($ROOT);
if ($ROOT_REAL !== false) $ROOT = $ROOT_REAL;

if (!is_dir($ROOT)) {
  json_out([
    'docs' => [],
    'error' => 'scan_root_not_found',
    'debug' => [
      'scan_root' => $ROOT,
      'realpath' => $ROOT_REAL,
      'open_basedir' => ini_get('open_basedir'),
    ],
  ], 200);
}

$BASE_URL = detect_base_url($cfg['base_url'] ?? null);

$allowedExt = (isset($cfg['allowed_ext']) && is_array($cfg['allowed_ext']))
  ? $cfg['allowed_ext']
  : ['pdf','doc','docx','xls','xlsx','ppt','pptx','zip','rtf','txt'];
$allowedExt = array_values(array_unique(array_map(fn($e) => strtolower((string)$e), $allowedExt)));

$excludeDirs = (isset($cfg['exclude_dirs']) && is_array($cfg['exclude_dirs']))
  ? $cfg['exclude_dirs']
  : ['_bak','default_files','szukaj','images','media'];
$excludeDirs = array_values(array_unique($excludeDirs));

$excludeFiles = ['.htaccess','.htpasswd','.htpasswd.bak','.htpasswd_bak'];

$maxFiles = isset($cfg['max_files']) ? (int)$cfg['max_files'] : 20000;
if ($maxFiles <= 0) $maxFiles = 20000;

// overrides
$overrides = [];
$overridesFile = __DIR__ . '/data/overrides.json';
if (is_file($overridesFile)) {
  $raw = @file_get_contents($overridesFile);
  if ($raw !== false && $raw !== '') {
    $j = json_decode($raw, true);
    if (is_array($j)) $overrides = $j;
  }
}

// cache
$cacheTtl = isset($cfg['cache_ttl']) ? (int)$cfg['cache_ttl'] : 0;
$cacheFile = __DIR__ . '/cache/docs.json';
if ($cacheTtl > 0 && is_file($cacheFile)) {
  $age = time() - (int)@filemtime($cacheFile);
  if ($age >= 0 && $age <= $cacheTtl) {
    $raw = @file_get_contents($cacheFile);
    if ($raw !== false && $raw !== '') {
      // cache powinien być już UTF-8; jakby coś, poleci przez normalny output
      echo $raw;
      exit;
    }
  }
}

// buduj indeks
$docs = [];
$errors = [];
$countFiles = 0;

scan_dir($ROOT, $ROOT, $BASE_URL, $allowedExt, $excludeDirs, $excludeFiles, $overrides, $docs, $errors, $countFiles, $maxFiles);

// sort
usort($docs, function($a, $b) {
  $sa = $a['section'] ?? '';
  $sb = $b['section'] ?? '';
  if ($sa === $sb) {
    return strcasecmp($a['title'] ?? '', $b['title'] ?? '');
  }
  return strcasecmp($sa, $sb);
});

$out = [
  'docs' => $docs,
  'meta' => [
    'count' => count($docs),
    'scan_root' => _fix_to_utf8($ROOT),
    'base_url' => _fix_to_utf8($BASE_URL),
  ],
];

if ($debug) {
  $out['debug'] = [
    'php' => PHP_VERSION,
    'open_basedir' => ini_get('open_basedir'),
    'errors' => array_slice(array_map('_fix_to_utf8', $errors), 0, 50),
    'scanned_files' => $countFiles,
    'max_files' => $maxFiles,
  ];
}

// zapisz cache jeśli się da
if ($cacheTtl > 0) {
  $payload = _normalize_for_json($out);
  $opts = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
  if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) $opts |= JSON_INVALID_UTF8_SUBSTITUTE;
  $json = json_encode($payload, $opts);
  if ($json !== false) {
    @file_put_contents($cacheFile, $json);
  }
}

json_out($out, 200);

Youez - 2016 - github.com/yon3zu
LinuXploit