배포된 애드온을 살펴보다가 한가지 의문이 생겨서 질문드립니다.

 

 

        foreach($filters as $filter)
        {
            eval("\$arr = ".$filter.";");
            if(is_array($arr))    $content = preg_replace($arr[0], $arr[1], $content);
        }

 

 

 

위와 같은 코드에서 eval("\$arr = ".$filter.";"); 이 등장을 하는데요.

$arr = $filter; 라고 작성해야 할 것 같은데  eval() 을 사용한 이유가 어떤 건지 궁금합니다.

 

아니 제가 지금 모르는 부분이 있어 위와 같은 생각을 한다면 

eval("\$arr = ".$filter.";"); 부분 자체가 왜 필요하지?? 라는 생각을 하게 되네요.

 

if(is_arra($filter)) 로 하면 되는거 아닌가? 하는 생각도 듭니다.

 

eval("\$arr = ".$filter.";"); 요게 등장해야 하는 이유가 뭔가요?

 

예상대로 eval() 함수부분 없이 작동은 안하네요.

 

  • profile

    $filter 부분에 PHP 코드를 직접 입력해도 그대로 실행되도록 하려고 한 것 같은데요.

     

    관리자만 입력할 수 있는 설정이라면 보안상 문제가 되지는 않겠지만,

    보안과 관련없이 eval()은 원칙적으로 모두 잘못되었다고 생각하셔도 무방합니다.

    사용자에게서 어떤 형태의 데이터를 입력받아서 어떻게 해석하여 어떤 자료구조로 저장할 것인지

    꼼꼼하게 따져서 설계하지 않고 그냥 코드 실행으로 퉁치려고 했다는 뜻이니까요.

  • profile profile

    네. 관리자만 입력할 수 있는 부분이라 그냥 써도 무방하긴 한데요.

    저기에 php 코드가 직접 실행되어야 하는 이유가 궁금했습니다.
    eval("\$arr = ".$filter.";");

    $arr = $filter; 와 어떤 차이가 나는건가요? 저부분에서....

     

     

    $filters = explode("\n", trim($addon_info->user_filter));

    이렇게 입력을 받은 것이 사용되고 입력 내용은 정규식입니다. 

    입력 자체를 array('pattern', 'replacement') 이렇게 넣고 있는 상황이구요.

  • profile profile

    $filter가 "array(1,2)"라는 문자열인 경우

    $arr = $filter; 는 $arr에 문자열 그대로 들어갑니다.

    eval()을 사용하면 $arr에 배열이 들어갑니다.

     

    밑에 is_array() 체크도 있는데 이게 어떤 차이를 만들어낼지는...

    $filter 자체가 처음부터 배열이라면 의미 없을지도요.

     

    한편, eval()을 사용하면 아래와 같은 무시무시한 코드를 사용할 수도 있습니다. ㅎㅎ

     

    array(1,2); getController('member')->deleteMember(Context::get('logged_info')->member_srl)

  • profile profile
    아... 값이 들어가 버리겠군요.

    그럼 eval()을 사용하지 않고
    array로 가지도록 하려면 별도 방법이 있을 것 같은데 어떻게 할까요?
  • profile profile

    제대로 설계한다면 처음부터 "1,2"라는 문자열을 받아서
    콤마를 기준으로 explode()하여 배열로 바꿔야겠지요.
    단, 배열에 포함된 값들 안에도 콤마가 들어갈 수 있다면 꽤 귀찮아질 수 있습니다.


    적당한 구분자를 찾는 것이 관건인데, 본문은 A를 B로 치환하는 기능인 듯 하니

    A => B 이런 문법을 임의로 만들어서 " => " 기준으로 explode()해도 되겠습니다.

  • profile profile
    애드온 설정에서 입력 받을때 다양한 정규식을 사용하게 해서 이것을 explode() 해서 가져왔는데

    이 배열을 순환시켜서 그 안의 입력 내용이 배열을 가르키는 array('pattern', 'replacement') 형태로 입력하게 하는 부분에서 오는 상황 같긴 합니다. 약간 제가 이해하는 부분이 흐릿하긴 하지만...

    입력 방법을 array(~~~) 가 아닌 방법으로 바꿔보는 시도를 해야 할 것 같다고 이해가 되네요.
  • profile profile
    자세한 설명으로 왜 eval() 함수에 의존해야 하는지 알것 같습니다. 애드온 입력에서 입력한 내용을 편하게 사용하기 위함 이었던 것으로 해석되네요.
  • profile profile
    //eval("\$arr = ".$filter.";");
    $arr = explode("=>", trim($filter));


    요렇게 바꾸로...

    애드온 입력에서 정규식 부분을
    @<a\b[^>]*>(.+?)</a>@is=>$1

    요런 형태로 입력하니 잘 되네요.

    오늘도 값진 지식 얻어 갑니다. 감사합니다.
  • profile
    eval.. 소스 코드 난독화 할 때 쓰는거 보긴 했네요