guterfreund
guterfreund

Reputation: 1

searching case-sensitive in txt-files

I have a php-script to search in my webspace-files. I can toggle (case) if I want to search case-sensitive. It function if I toggle case-sensitive. But when deselect this option I get no result if my word is in upper-case. So I think that the script lowers every time. But I can't find, even now after hours, what is wrong...

PHP 8.3

search_all.php on my webspace

The script gives me results. So if you try on the website linked above with the german Geist (=ghost) it gives me with toggled on "case-sensitive" 138 hits. But with toggled off it gives me "Sorry No Result Found." even so the result must have been 159. So I think there must be a fault with the strtolower-command?

Any idea?

If I insert the whole script, I dont get an error in the php-sandbox on [PHP Sandbox][1] heres the the part of script which handles "case":

<?php
$count = 0;

function getDirContents($dir, &$results = array()) {
    global $count;
    $searchStrings = array();

    if(isset($_POST['searchStrings'])) 
        $searchStrings = json_decode($_POST['searchStrings'], true);
    
    if ($_POST['search'] == null) { echo "1"; exit;}
    
    ini_set('max_execution_time', $_POST['maxtime']);
    
    $_SESSION['searchString'] = $_POST['search'];
    
    echo "<script>var elm = document.getElementById('search');elm.value='$_POST[search]';</script>";
    
    if (!isset($_POST['case']))
        $string = strtolower($_POST['search'] ?? '');
    else 
        $string = $_POST['search'];
    
    $files = scandir($dir);
    
    foreach ($files as $key => $value) {
        $path = realpath($dir . DIRECTORY_SEPARATOR . $value);
        if (!is_dir($path)) {
            if (!isset($_POST['case'])) 
                $content = strtolower(file_get_contents($path));
            else 
                $content = file_get_contents($path);

            $label = null;
            $fileName = basename($path, '?' . $_SERVER['QUERY_STRING']);
            $type = null;
            $types = array();...

So it must be an error, that the PHP-Sandbox can`t find...

Upvotes: 0

Views: 74

Answers (3)

guterfreund
guterfreund

Reputation: 1

The solution was:

if (!isset($_POST['case'])) {
    $string = strtolower($_POST['search'] ?? '');
}else {
    $string = $_POST['search'] ?? '';
} 

was on the wrong position it should be under foreach , and instead of $string I used now $tmp

$files = scandir($dir);

foreach ($files as $key => $value) {
    $path = realpath($dir . DIRECTORY_SEPARATOR . $value);
    if (!is_dir($path)) {
        if (!isset($_POST['case'])) {
            $content = strtolower(file_get_contents($path));
        }else {
            $content = file_get_contents($path);
        }
        $label = null;
        $fileName = basename($path, '?' . $_SERVER['QUERY_STRING']);
        $type = null;
        $types = array();
    
        foreach ($searchStrings as $tmp) {
        
            if (!isset($_POST['case'])) {
                $tmp = strtolower($_POST['search'] ?? '');
            }else {
                $tmp = $_POST['search'] ?? '';
            }

Upvotes: 0

Julien D Biniou
Julien D Biniou

Reputation: 46

For simple search maybe you can do something like this

$stringInWhichSearching = "Hello world, Geist is here.";
$search = "geist";
$caseSensitiveSearch = false;

if($caseSensitiveSearch === true) {
    // strpos is case sensitive
    $foundAtIndex = strpos($stringInWhichSearching, $search);
}
else {
    // stripos is case insensitive
    $foundAtIndex = stripos($stringInWhichSearching, $search);
}
if($foundAtIndex !== false) {
    echo "found at index $foundAtIndex" . PHP_EOL;
}
else {
    echo "not found" . PHP_EOL;
}

Solution with count handling

$stringInWhichSearching = "Hello world, Geist is here.";
$search = "geist";
$caseSensitiveSearch = false;
$pattern = preg_quote($search, '/');

if($caseSensitiveSearch === true) {
    // the option 'u' is for unicode
    $count = preg_match_all("/$pattern/u", $stringInWhichSearching, $matches);
}
else {
    // the option 'u' is for unicode, "i" is for case insensitive
    $count = preg_match_all("/$pattern/ui", $stringInWhichSearching, $matches);
}
echo "Founded $count times" . PHP_EOL;

Warning

Here is an XSS security issue

echo "<script>var elm = document.getElementById('search');elm.value='$_POST[search]';</script>";

if $_POST[search] contains javascript, it is possible to do bad things

Upvotes: 0

Ahmad Ameri
Ahmad Ameri

Reputation: 400

When you want to compare to strings in a case-insensitive way you have to convert both strings to lower (or upper).

if(strtolower($str_a) == strtolower($str_b)){
    // match
}

As your code is incomplete and in the shown part only one of strings is converted to lower case, I think you have forgot to convert the other string to lower.

Upvotes: 0

Related Questions