source

문자열이 직렬화되었는지 확인하시겠습니까?

goodcode 2022. 11. 5. 11:41
반응형

문자열이 직렬화되었는지 확인하시겠습니까?

문자열이 이 문자열의 결과인지 아닌지를 판별하는 가장 좋은 방법은 무엇입니까?serialize()기능하고 있습니까?

https://www.php.net/manual/en/function.serialize

한번 해봐라;-)

매뉴얼 인용:

전달된 문자열이 시리얼화 불가능할 경우 FALSE가 반환되고 E_NOTICE가 발행됩니다.

따라서 반환값이 다음과 같은지 확인해야 합니다.false또는 그렇지 않은 경우(또는 과 같은 문제 또는 이와 동등한 것에 문제가 없는지 확인합니다).

주의사항만 주의해주세요.@ 연산자를 사용해야 할 수도 있습니다.

예:

$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
    echo "ok";
} else {
    echo "not ok";
}

다음 정보를 얻을 수 있습니다.

not ok


편집 : 아, 그리고 @Peter가 말한 것처럼 (덕분에!) 부울 false의 표현을 시리얼화 해제하려고 하면 문제가 발생할 수 있습니다.

따라서 시리얼화된 문자열이 "와 같지 않은지 확인합니다.b:0;"도움이 될 수 있습니다.이러한 방법이 도움이 될 것 같아요.

$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
    echo "ok";
} else {
    echo "not ok";
}

시리얼화를 해제하기 전에 이 특수한 경우를 테스트하는 것은 최적화입니다.그러나 잘못된 시리얼화 값이 없는 경우는 그다지 유용하지 않을 수 있습니다.

WordPress 핵심 기능:

<?php
function is_serialized( $data, $strict = true ) {
    // If it isn't a string, it isn't serialized.
    if ( ! is_string( $data ) ) {
        return false;
    }
    $data = trim( $data );
    if ( 'N;' === $data ) {
        return true;
    }
    if ( strlen( $data ) < 4 ) {
        return false;
    }
    if ( ':' !== $data[1] ) {
        return false;
    }
    if ( $strict ) {
        $lastc = substr( $data, -1 );
        if ( ';' !== $lastc && '}' !== $lastc ) {
            return false;
        }
    } else {
        $semicolon = strpos( $data, ';' );
        $brace     = strpos( $data, '}' );
        // Either ; or } must exist.
        if ( false === $semicolon && false === $brace ) {
            return false;
        }
        // But neither must be in the first X characters.
        if ( false !== $semicolon && $semicolon < 3 ) {
            return false;
        }
        if ( false !== $brace && $brace < 4 ) {
            return false;
        }
    }
    $token = $data[0];
    switch ( $token ) {
        case 's':
            if ( $strict ) {
                if ( '"' !== substr( $data, -2, 1 ) ) {
                    return false;
                }
            } elseif ( false === strpos( $data, '"' ) ) {
                return false;
            }
            // Or else fall through.
        case 'a':
        case 'O':
            return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
        case 'b':
        case 'i':
        case 'd':
            $end = $strict ? '$' : '';
            return (bool) preg_match( "/^{$token}:[0-9.E+-]+;$end/", $data );
    }
    return false;
} 

Pascal MARTIN 응답 최적화

/**
 * Check if a string is serialized
 * @param string $string
 */
public static function is_serial($string) {
    return (@unserialize($string) !== false);
}

$string이 시리얼화된 경우false값, 즉$string = 'b:0;' SoN9NE 함수 반환false,그것은 잘못된 것입니다.

그래서 함수는

/**
 * Check if a string is serialized
 *
 * @param string $string
 *
 * @return bool
 */
function is_serialized_string($string)
{
    return ($string == 'b:0;' || @unserialize($string) !== false);
}

파스칼 MARTIN의 훌륭한 답변에도 불구하고, 다른 방법으로 접근해 주실 수 있는지 궁금해서 그냥 정신적인 운동으로 이렇게 했습니다.

<?php

ini_set( 'display_errors', 1 );
ini_set( 'track_errors', 1 );
error_reporting( E_ALL );

$valueToUnserialize = serialize( false );
//$valueToUnserialize = "a"; # uncomment this for another test

$unserialized = @unserialize( $valueToUnserialize );

if ( FALSE === $unserialized && isset( $php_errormsg ) && strpos( $php_errormsg, 'unserialize' ) !== FALSE )
{
  echo 'Value could not be unserialized<br>';
  echo $valueToUnserialize;
} else {
  echo 'Value was unserialized!<br>';
  var_dump( $unserialized );
}

그리고 그것은 실제로 작동한다.유일한 주의사항은 $php_errormsg의 동작으로 인해 등록된 오류 핸들러가 있는 경우 오류가 발생할 수 있다는 것입니다.

$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
    echo 'ok';
else
    echo "not ok";

의 경우를 올바르게 처리합니다.serialize(false). :)

함수에 짜넣다

function isSerialized($value)
{
   return preg_match('^([adObis]:|N;)^', $value);
}

Word Press 솔루션이 있습니다. (자세한 내용은 이쪽)

    function is_serialized($data, $strict = true)
    {
        // if it isn't a string, it isn't serialized.
        if (!is_string($data)) {
            return false;
        }
        $data = trim($data);
        if ('N;' == $data) {
            return true;
        }
        if (strlen($data) < 4) {
            return false;
        }
        if (':' !== $data[1]) {
            return false;
        }
        if ($strict) {
            $lastc = substr($data, -1);
            if (';' !== $lastc && '}' !== $lastc) {
                return false;
            }
        } else {
            $semicolon = strpos($data, ';');
            $brace = strpos($data, '}');
            // Either ; or } must exist.
            if (false === $semicolon && false === $brace)
                return false;
            // But neither must be in the first X characters.
            if (false !== $semicolon && $semicolon < 3)
                return false;
            if (false !== $brace && $brace < 4)
                return false;
        }
        $token = $data[0];
        switch ($token) {
            case 's' :
                if ($strict) {
                    if ('"' !== substr($data, -2, 1)) {
                        return false;
                    }
                } elseif (false === strpos($data, '"')) {
                    return false;
                }
            // or else fall through
            case 'a' :
            case 'O' :
                return (bool)preg_match("/^{$token}:[0-9]+:/s", $data);
            case 'b' :
            case 'i' :
            case 'd' :
                $end = $strict ? '$' : '';
                return (bool)preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
        }
        return false;
    }
/**
 * some people will look down on this little puppy
 */
function isSerialized($s){
if(
    stristr($s, '{' ) != false &&
    stristr($s, '}' ) != false &&
    stristr($s, ';' ) != false &&
    stristr($s, ':' ) != false
    ){
    return true;
}else{
    return false;
}

}

이것으로 충분합니다.

<?php

function is_serialized($data){
    return (is_string($data) && preg_match("#^((N;)|((a|O|s):[0-9]+:.*[;}])|((b|i|d):[0-9.E-]+;))$#um", $data));
    }

?>

나는 그냥 그것을 해제하려고 노력할 것이다.나는 이렇게 해결할 것이다.

public static function is_serialized($string)
{
    try {
        unserialize($string);
    } catch (\Exception $e) {
        return false;
    }

    return true;
}

또는 도우미 기능에 가깝습니다.

function is_serialized($string) {
  try {
        unserialize($string);
    } catch (\Exception $e) {
        return false;
    }

    return true;
}
  • 언급된 WordPress 함수는 실제로 어레이를 감지하지 않습니다(a:1:{42}시리얼화 된 것으로 간주되어 잘못된 반환을 합니다.true와 같은 탈옥한 끈으로a:1:{s:3:\"foo\";s:3:\"bar\";}(단,unserialize동작하지 않는다)

  • 를 사용하는 경우@unserialize예를 들어 WordPress의 다른 쪽 방법은 백엔드 상단에 보기 흉한 여백을 추가합니다.define('WP_DEBUG', true);

여기에 이미지 설명 입력

  • 두 가지 문제를 해결하고 stfu-operator를 우회하는 효과적인 솔루션은 다음과 같습니다.
function __is_serialized($var)
{
    if (!is_string($var) || $var == '') {
        return false;
    }
    set_error_handler(function ($errno, $errstr) {});
    $unserialized = unserialize($var);
    restore_error_handler();
    if ($var !== 'b:0;' && $unserialized === false) {
        return false;
    }
    return true;
}

워드프레스 함수 is_signized를 참조하십시오.

function is_serialized( $data, $strict = true ) {
// If it isn't a string, it isn't serialized.
if ( ! is_string( $data ) ) {
    return false;
}
$data = trim( $data );
if ( 'N;' === $data ) {
    return true;
}
if ( strlen( $data ) < 4 ) {
    return false;
}
if ( ':' !== $data[1] ) {
    return false;
}
if ( $strict ) {
    $lastc = substr( $data, -1 );
    if ( ';' !== $lastc && '}' !== $lastc ) {
        return false;
    }
} else {
    $semicolon = strpos( $data, ';' );
    $brace     = strpos( $data, '}' );
    // Either ; or } must exist.
    if ( false === $semicolon && false === $brace ) {
        return false;
    }
    // But neither must be in the first X characters.
    if ( false !== $semicolon && $semicolon < 3 ) {
        return false;
    }
    if ( false !== $brace && $brace < 4 ) {
        return false;
    }
}
$token = $data[0];
switch ( $token ) {
    case 's':
        if ( $strict ) {
            if ( '"' !== substr( $data, -2, 1 ) ) {
                return false;
            }
        } elseif ( false === strpos( $data, '"' ) ) {
            return false;
        }
        // Or else fall through.
    case 'a':
    case 'O':
        return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
    case 'b':
    case 'i':
    case 'd':
        $end = $strict ? '$' : '';
        return (bool) preg_match( "/^{$token}:[0-9.E+-]+;$end/", $data );
}
return false;

}

언급URL : https://stackoverflow.com/questions/1369936/check-to-see-if-a-string-is-serialized

반응형