sourcecode

문자열 검사기, 파일 이름

copyscript 2023. 1. 10. 21:16
반응형

문자열 검사기, 파일 이름

문자열을 삭제하여 파일명으로 사용할 수 있는 php 함수를 찾고 있습니다.편리한 거 아는 사람?

(글씨는 쓸 수 있지만, 글자를 간과할까 봐 걱정입니다!)

편집: Windows NTFS 파일 시스템에 파일을 저장합니다.

Domino Rodger가 발견한 문제를 해결하기 위해 Tor Valamo의 솔루션을 약간 조정하면 다음을 사용할 수 있습니다.

// Remove anything which isn't a word, whitespace, number
// or any of the following caracters -_~,;[]().
// If you don't need to handle multi-byte characters
// you can use preg_replace rather than mb_ereg_replace
// Thanks @Łukasz Rysiak!
$file = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $file);
// Remove any runs of periods (thanks falstro!)
$file = mb_ereg_replace("([\.]{2,})", '', $file);

이렇게 하면 파일 시스템의 파일 이름을 필요에 따라 삭제할 수 있습니다.

function filter_filename($name) {
    // remove illegal file system characters https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
    $name = str_replace(array_merge(
        array_map('chr', range(0, 31)),
        array('<', '>', ':', '"', '/', '\\', '|', '?', '*')
    ), '', $name);
    // maximise filename length to 255 bytes http://serverfault.com/a/9548/44086
    $ext = pathinfo($name, PATHINFO_EXTENSION);
    $name= mb_strcut(pathinfo($name, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($name)) . ($ext ? '.' . $ext : '');
    return $name;
}

파일 시스템에서는 다른 모든 것이 허용되므로 질문에 완벽하게 답변할 수 있습니다.

...하지만 예를 들어 작은 따옴표를 허용하면 위험할 수 있습니다.'안전하지 않은 HTML 컨텍스트에서 나중에 사용할 경우 파일명으로 지정합니다.이는 완전히 합법적인 파일명이기 때문입니다.

 ' onerror= 'alert(document.cookie).jpg

XSS 홀이 됩니다.

<img src='<? echo $image ?>' />
// output:
<img src=' ' onerror= 'alert(document.cookie)' />

이 때문에 인기 있는 CMS 소프트웨어 Wordpress는 이러한 문자를 제거하지만 일부 업데이트 후에만 모든 관련 문자를 포함했습니다.

$special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
// ... a few rows later are whitespaces removed as well ...
preg_replace( '/[\r\n\t -]+/', '-', $filename )

마지막으로 이들 목록에는 URI 재지정 문자 및 URL 안전하지 않은 문자 목록의 일부인 대부분의 문자가 포함됩니다.

물론 HTML 출력에 이러한 문자를 모두 인코딩할 수 있지만, 대부분의 개발자와 나도 "Better safe ban sorry"라는 관용어를 따라 미리 삭제합니다.

마지막으로 다음을 사용할 것을 제안합니다.

function filter_filename($filename, $beautify=true) {
    // sanitize filename
    $filename = preg_replace(
        '~
        [<>:"/\\\|?*]|            # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
        [\x00-\x1F]|             # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
        [\x7F\xA0\xAD]|          # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
        [#\[\]@!$&\'()+,;=]|     # URI reserved https://www.rfc-editor.org/rfc/rfc3986#section-2.2
        [{}^\~`]                 # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
        ~x',
        '-', $filename);
    // avoids ".", ".." or ".hiddenFiles"
    $filename = ltrim($filename, '.-');
    // optional beautification
    if ($beautify) $filename = beautify_filename($filename);
    // maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    $filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
    return $filename;
}

파일 시스템에서 문제를 일으키지 않는 다른 모든 항목은 추가 기능의 일부여야 합니다.

function beautify_filename($filename) {
    // reduce consecutive characters
    $filename = preg_replace(array(
        // "file   name.zip" becomes "file-name.zip"
        '/ +/',
        // "file___name.zip" becomes "file-name.zip"
        '/_+/',
        // "file---name.zip" becomes "file-name.zip"
        '/-+/'
    ), '-', $filename);
    $filename = preg_replace(array(
        // "file--.--.-.--name.zip" becomes "file.name.zip"
        '/-*\.-*/',
        // "file...name..zip" becomes "file.name.zip"
        '/\.{2,}/'
    ), '.', $filename);
    // lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
    $filename = mb_strtolower($filename, mb_detect_encoding($filename));
    // ".file-name.-" becomes "file-name"
    $filename = trim($filename, '.-');
    return $filename;
}

이 시점에서 결과가 비어 있고 UTF-8 문자를 인코딩할지 여부를 결정할 수 있는 경우 파일 이름을 생성해야 합니다.그러나 UTF-8은 웹 호스팅 컨텍스트에서 사용되는 모든 파일시스템에서 허용되므로 이 기능은 필요하지 않습니다.

요.urlencode()를 희망합니다) 이름('URL')은საბეჭდი_მანქანა.jpg는, 「URL」로서 이 이 .<img src> ★★★★★★★★★★★★★★★★★」<a href>: http://www.maxrev.de/html/img/%E1%83%A1%E1%83%90%E1%83%91%E1%83%94%E1%83%AD%E1%83%93%E1%83%98_%E1%83%9B%E1%83%90%E1%83%9C%E1%83%A5%E1%83%90%E1%83%9C%E1%83%90.jpg

Stackoverflow는 이 기능을 하기 때문에 사용자가 하는 것처럼 이 링크를 게시할 수 있습니다.
http://www.maxrev.de/html/img/ jpjpjp.jptt www.maxrev.de/html/img/

따라서 이것은 완전한 법적 파일명으로, as@SequenceDigitale.com가 의 답변에서 언급한 문제는 아닙니다.

솔루션 1 - 심플하고 효과적

$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );

  • strtolower()는 파일명이 소문자임을 보증합니다(URL 내부에서는 대소문자가 상관없지만 NTFS 파일명에서는 대소문자가 중요함).
  • [^a-z0-9]+합니다.
  • substit로 바꿉니다.'-'합니다.

예:

URL:  http://stackoverflow.com/questions/2021624/string-sanitizer-for-filename
File: http-stackoverflow-com-questions-2021624-string-sanitizer-for-filename

솔루션 2 - 매우 긴 URL용

URL 내용을 캐시하고 고유한 파일 이름만 있으면 됩니다.다음 기능을 사용합니다.

$file_name = md5( strtolower( $url ) )

고정 길이의 파일 이름이 생성됩니다.MD5 해시는 대부분의 경우 이러한 용도로 충분히 고유합니다.

예:

URL:  https://www.amazon.com/Interstellar-Matthew-McConaughey/dp/B00TU9UFTS/ref=s9_nwrsa_gw_g318_i10_r?_encoding=UTF8&fpl=fresh&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-1&pf_rd_r=BS5M1H560SMAR2JDKYX3&pf_rd_r=BS5M1H560SMAR2JDKYX3&pf_rd_t=36701&pf_rd_p=6822bacc-d4f0-466d-83a8-2c5e1d703f8e&pf_rd_p=6822bacc-d4f0-466d-83a8-2c5e1d703f8e&pf_rd_i=desktop
File: 51301f3edb513f6543779c3a5433b01c

rawurlencode() ?http://www.php.net/manual/en/function.rawurlencode.php 를 사용하는 것은 어떨까요?

중국어 문자까지 삭제하는 기능은 다음과 같습니다.

public static function normalizeString ($str = '')
{
    $str = strip_tags($str); 
    $str = preg_replace('/[\r\n\t ]+/', ' ', $str);
    $str = preg_replace('/[\"\*\/\:\<\>\?\'\|]+/', ' ', $str);
    $str = strtolower($str);
    $str = html_entity_decode( $str, ENT_QUOTES, "utf-8" );
    $str = htmlentities($str, ENT_QUOTES, "utf-8");
    $str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
    $str = str_replace(' ', '-', $str);
    $str = rawurlencode($str);
    $str = str_replace('%', '-', $str);
    return $str;
}

여기 설명이 있습니다.

  1. HTML 태그 삭제
  2. 파손/탭/반환 캐리지 제거
  3. 폴더 및 파일 이름의 잘못된 문자 제거
  4. 문자열은 소문자로 입력합니다.
  5. à by 등의 외래 악센트를 html 엔티티로 변환하여 삭제한 후 코드를 삭제하고 문자를 유지합니다.
  6. 공간을 대시로 바꾸기
  7. 이전 단계를 통과하여 서버에서 충돌하는 파일 이름을 입력할 수 있는 특수 문자를 인코딩합니다.ex. "中文百强网"
  8. 파일을 쿼리할 때 브라우저에 의해 파일 링크가 다시 작성되지 않도록 하려면 "%"를 대시로 바꿉니다.

네, 일부 파일명은 관련이 없지만 대부분의 경우 작동합니다.

예: 원래 이름 : "ააჭდდ-დდ-ტტტ-ტjjjjjjj.jpg"

출력명 : "-E1-83-A1-83-90-E1-83-91-E1-83-94-E1-83-AD-E1-83-E1-83-98--E1-83-93-E1-83-90--E1-83-E-83-E-198"

404 오류보다는 낫습니다.

도움이 됐으면 좋겠네요.

칼.

캐릭터를 간과하는 것에 대해 걱정할 것이 아니라, 자신이 사용하고 싶은 캐릭터의 화이트리스트를 사용하는 것은 어떻습니까?를 들어,ol' all' ㄹ 수 있다, 좋은 ol' ㄹ 수 , 라고 할 수 .a-z,0-9,_ 「」)의 단일 「」 「」 「」).대부분의 파일 시스템보다 훨씬 제한적이지만 안전하게 보호됩니다.

음, tempnam()이 대신 해줄게요.

http://us2.php.net/manual/en/function.tempnam.php

완전히 새로운 이름이 탄생하게 됩니다.

기존 문자열을 삭제하려면 사용자가 입력할 수 있는 문자열을 제한하고 문자, 숫자, 마침표, 하이픈 및 밑줄로 만든 다음 간단한 regex로 삭제합니다.이스케이프할 필요가 있는 문자를 확인합니다.그렇지 않으면 false positive를 얻을 수 있습니다.

$sanitized = preg_replace('/[^a-zA-Z0-9\-\._]/','', $filename);
preg_replace("[^\w\s\d\.\-_~,;:\[\]\(\]]", '', $file)

시스템에 허용되는 문자에 따라 더 많은 유효한 문자를 추가/제거합니다.

또는 파일을 만든 후 오류가 발생할 경우 오류를 반환할 수 있습니다.

safe: "a-zA-Z0-9_"가 아닌 모든 시퀀스를 대시로 바꾸고 직접 확장자를 추가합니다.

$name = preg_replace('/[^a-zA-Z0-9_-]+/', '-', strtolower($name)).'.'.$extension;

그래서 PDF가

"This is a grüte test_service +/-30 thing"

된다

"This-is-a-gr-te-test_service-30-thing.pdf"

PHP는 텍스트를 다른 형식으로 삭제하는 기능을 제공합니다.

filter.syslog.sysize

방법:

echo filter_var(
   "Lorem Ipsum has been the industry's",FILTER_SANITIZE_URL
); 

따옴표LoremIpsumhasbeentheindustry's

Sean Vieira의 솔루션을 약간 조정하여 하나의 점을 사용할 수 있습니다.

preg_replace("([^\w\s\d\.\-_~,;:\[\]\(\)]|[\.]{2,})", '', $file)

다음 표현은 멋지고 깨끗한 사용 가능한 문자열을 만듭니다.

/[^a-z0-9\._-]+/gi

오늘의 재무: 과금을 오늘의 재무 과금으로 전환

어떤 이든 "끈으로 할 수 있을 합니다.en스타일 파일 이름 또는 폴더 이름(혹은 스크럽된 슬래그나 구부릴 경우)을 지정합니다.

1) 풀 파일명 구축(입력 내용이 완전히 잘린 경우 폴백 이름 포함):

str_file($raw_string, $word_separator, $file_extension, $fallback_name, $length);

2)파일명을 하지 않고 mode 2) util util ( strict mode 2) ( strict ) 。true에서는 파일 이름에 [] 또는 ()를 사용할 수 없습니다.

str_file_filter($string, $separator, $strict, $length);

3) 이러한 기능은 다음과 같습니다.

// Returns filesystem-safe string after cleaning, filtering, and trimming input
function str_file_filter(
    $str,
    $sep = '_',
    $strict = false,
    $trim = 248) {

    $str = strip_tags(htmlspecialchars_decode(strtolower($str))); // lowercase -> decode -> strip tags
    $str = str_replace("%20", ' ', $str); // convert rogue %20s into spaces
    $str = preg_replace("/%[a-z0-9]{1,2}/i", '', $str); // remove hexy things
    $str = str_replace("&nbsp;", ' ', $str); // convert all nbsp into space
    $str = preg_replace("/&#?[a-z0-9]{2,8};/i", '', $str); // remove the other non-tag things
    $str = preg_replace("/\s+/", $sep, $str); // filter multiple spaces
    $str = preg_replace("/\.+/", '.', $str); // filter multiple periods
    $str = preg_replace("/^\.+/", '', $str); // trim leading period

    if ($strict) {
        $str = preg_replace("/([^\w\d\\" . $sep . ".])/", '', $str); // only allow words and digits
    } else {
        $str = preg_replace("/([^\w\d\\" . $sep . "\[\]\(\).])/", '', $str); // allow words, digits, [], and ()
    }

    $str = preg_replace("/\\" . $sep . "+/", $sep, $str); // filter multiple separators
    $str = substr($str, 0, $trim); // trim filename to desired length, note 255 char limit on windows

    return $str;
}


// Returns full file name including fallback and extension
function str_file(
    $str,
    $sep = '_',
    $ext = '',
    $default = '',
    $trim = 248) {

    // Run $str and/or $ext through filters to clean up strings
    $str = str_file_filter($str, $sep);
    $ext = '.' . str_file_filter($ext, '', true);

    // Default file name in case all chars are trimmed from $str, then ensure there is an id at tail
    if (empty($str) && empty($default)) {
        $str = 'no_name__' . date('Y-m-d_H-m_A') . '__' . uniqid();
    } elseif (empty($str)) {
        $str = $default;
    }

    // Return completed string
    if (!empty($ext)) {
        return $str . $ext;
    } else {
        return $str;
    }
}

은 다음과 같습니다......&lt;div&gt;&lt;/div&gt;<script></script>&amp; Weiß Göbel 中文百强网File name %20 %20 %21 %2C Décor \/. /. . z \... y \...... x ./ “This name” is & 462^^ not &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = that grrrreat -][09]()1234747) საბეჭდი-და-ტიპოგრაფიული

파일 이름 길이가 255자인 tar.gz를 만들기 위해 좀 더 친근한 것으로 변환하고 싶습니다.다음은 사용 예를 제시하겠습니다.주의: 이 예에는 잘못된 형식의 tar.gz 확장자가 개념 증명으로 포함되어 있습니다.이 경우 문자열이 화이트리스트에 대해 작성된 후에도 ext를 필터링해야 합니다.

$raw_str = '.....&lt;div&gt;&lt;/div&gt;<script></script>&amp; Weiß Göbel 中文百强网File name  %20   %20 %21 %2C Décor  \/.  /. .  z \... y \...... x ./  “This name” is & 462^^ not &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = that grrrreat -][09]()1234747) საბეჭდი-და-ტიპოგრაფიული';
$fallback_str = 'generated_' . date('Y-m-d_H-m_A');
$bad_extension = '....t&+++a()r.gz[]';

echo str_file($raw_str, '_', $bad_extension, $fallback_str);

은 다음과 _wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz

https://3v4l.org/iSgi8 에서 플레이 할 수 있습니다.

또는 Gist: https://gist.github.com/dhaupin/b109d3a8464239b7754a

EDIT: 스크립트필터 갱신&nbsp; 대신 3v4l 3v4l

현재 가장 잘 알고 있는 것은 Nette 프레임워크에서 Strings:: webalize라는 정적 메서드입니다.

그나저나, 모든 발음 구별 부호가 기본 부호로 변환됩니다.sh=>s ü=>u u =>ss 등

파일 이름의 경우 허용된 문자 매개 변수에 점 "."을 추가해야 합니다.

/**
 * Converts to ASCII.
 * @param  string  UTF-8 encoding
 * @return string  ASCII
 */
public static function toAscii($s)
{
    static $transliterator = NULL;
    if ($transliterator === NULL && class_exists('Transliterator', FALSE)) {
        $transliterator = \Transliterator::create('Any-Latin; Latin-ASCII');
    }

    $s = preg_replace('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{2FF}\x{370}-\x{10FFFF}]#u', '', $s);
    $s = strtr($s, '`\'"^~?', "\x01\x02\x03\x04\x05\x06");
    $s = str_replace(
        array("\xE2\x80\x9E", "\xE2\x80\x9C", "\xE2\x80\x9D", "\xE2\x80\x9A", "\xE2\x80\x98", "\xE2\x80\x99", "\xC2\xB0"),
        array("\x03", "\x03", "\x03", "\x02", "\x02", "\x02", "\x04"), $s
    );
    if ($transliterator !== NULL) {
        $s = $transliterator->transliterate($s);
    }
    if (ICONV_IMPL === 'glibc') {
        $s = str_replace(
            array("\xC2\xBB", "\xC2\xAB", "\xE2\x80\xA6", "\xE2\x84\xA2", "\xC2\xA9", "\xC2\xAE"),
            array('>>', '<<', '...', 'TM', '(c)', '(R)'), $s
        );
        $s = @iconv('UTF-8', 'WINDOWS-1250//TRANSLIT//IGNORE', $s); // intentionally @
        $s = strtr($s, "\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e"
            . "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
            . "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
            . "\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
            . "\x96\xa0\x8b\x97\x9b\xa6\xad\xb7",
            'ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt- <->|-.');
        $s = preg_replace('#[^\x00-\x7F]++#', '', $s);
    } else {
        $s = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); // intentionally @
    }
    $s = str_replace(array('`', "'", '"', '^', '~', '?'), '', $s);
    return strtr($s, "\x01\x02\x03\x04\x05\x06", '`\'"^~?');
}


/**
 * Converts to web safe characters [a-z0-9-] text.
 * @param  string  UTF-8 encoding
 * @param  string  allowed characters
 * @param  bool
 * @return string
 */
public static function webalize($s, $charlist = NULL, $lower = TRUE)
{
    $s = self::toAscii($s);
    if ($lower) {
        $s = strtolower($s);
    }
    $s = preg_replace('#[^a-z0-9' . preg_quote($charlist, '#') . ']+#i', '-', $s);
    $s = trim($s, '-');
    return $s;
}

이 모든 것은 서버 해킹(또는 기타 손상)에 사용할 수 있는 파일명을 작성하는 것이 가능한가에 달려 있는 것 같습니다.그렇지 않은 경우, 최종적으로는 파일을 사용하는 장소에 관계없이 파일을 작성하는 것이 가장 간단한 해답인 것 같습니다(이것은 틀림없이, operating system이 되기 때문입니다).operating system에 의해서 해결됩니다.문제가 발생했을 경우는, 그 문제를 검증 에러로서 유저에게 되돌립니다.

그 OS의 파일명이 올바르게 형성되어 있지 않으면 모든 운영체제가 불만을 제기하기 때문에, 이 기능은 확실히 휴대할 수 있다는 장점이 있습니다.

파일명을 사용해 귀찮은 일을 할 수 있는 경우는, 상주하는 operating system으로 파일명을 테스트하기 전에 적용할 수 있는 방법이 있습니다.파일명의 완전한 「위생」보다 간단한 방법입니다.

편도

$bad='/[\/:*?"<>|]/';
$string = 'fi?le*';

function sanitize($str,$pat)
{
    return preg_replace($pat,"",$str);

}
echo sanitize($string,$bad);

/그리고...사용자 지정 파일 이름에서 유해할 수 있습니다.따라서 다음과 같은 방법으로 이러한 항목을 제거해야 합니다.

$fname = str_replace('..', '', $fname);
$fname = str_replace('/',  '', $fname);
function sanitize_file_name($file_name) { 
 // case of multiple dots
  $explode_file_name =explode('.', $file_name);
  $extension =array_pop($explode_file_name);
  $file_name_without_ext=substr($file_name, 0, strrpos( $file_name, '.') );    
  // replace special characters
  $file_name_without_ext = preg_quote($file_name_without_ext);
  $file_name_without_ext = preg_replace('/[^a-zA-Z0-9\\_]/', '_', $file_name_without_ext);
  $file_name=$file_name_without_ext . '.' . $extension;    
  return $file_name;
}

$fname = str_replacefacebook/'',$fname);

사용자가 슬래시를 사용하여 두 단어를 구분할 수 있으므로 NULL 대신 대시로 바꾸는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/2021624/string-sanitizer-for-filename

반응형