2012-02-18 3 views
0

아래 스크립트의 출력은 다음과 같습니다루아에서 키 값을 가진 테이블을 어떻게 참조합니까?

AD[1] = [variable not found] 
AD['2'] = bar 

어떻게 두 경우 모두에 대한 V의 값을 반환하는 함수 getfield을 수정할 수 있습니다?

function getfield (f) 
    local v = _G  
    for w in string.gfind(f, "[%w_]+") do 
    v = v[w] 
    end 
return v 
end 

AD = {[1] = 'foo', ['2'] = 'bar'} 
data = {"AD[1]","AD['2']"} 

for i,line in ipairs(data) do 
    s = getfield(line) 
    if s then 
     print(line .. " = " .. s) 
    else 
    print(line .. " = [variable not found]") 
    end 
end 

UPDATE : 나는 90 % 확신이 나를 위해 일을하려고 해요 :

function getfield (f) 
    local v = _G  
    for w in string.gfind(f, "['%w_]+") do 
     if (string.find(w,"['%a_]")==nil) then 
     w = loadstring('return '..w)() 
     else 
     w = string.gsub(w, "'", "") 
     end 
     v=v[w] 
    end 
    return v 
end 

답변

1

이것은

function getfield (f) 
    local v = _G  
    for w in string.gfind(f, "['%w_]+") do 
    local x = loadstring('return '..w)() 
    print(w,x) 
    v = v[x] or v[w] 
    end 
return v 
end 

AD = {[1] = 'foo', ['2'] = 'bar'} 
data = {"AD[1]","AD['2']"} 

for i,line in ipairs(data) do 
    s = getfield(line) 
    if s then 
     print(line .. " = " .. s) 
    else 
    print(line .. " = [variable not found]") 
    end 
end 

을 일이 발생하지만 매우 취약합니다.

패턴에 '을 추가했음을 유의하십시오.

때때로 w는 이름 (키)을 나타내는 문자열이며 때로는 숫자를 나타내는 문자열입니다. 두 번째 경우에는 문자열에서 숫자로 변환해야합니다. 그러나 문맥이나 구문을 결정해야합니다.

여기 내 말은 취약성의 종류 :

>  data = {"math[pi]","AD['2']"} 
>  
>  for i,line in ipairs(data) do 
>>  s = getfield(line) 
>>  if s then 
>>    print(line .. " = " .. s) 
>>  else 
>>   print(line .. " = [variable not found]") 
>>  end 
>>  end 
math table: 0x10ee05100 
pi nil 
math[pi] = 3.1415926535898 
AD table: 0x10ee19ee0 
'2' 2 
AD['2'] = bar 


> pi = 3 
> math[3] = 42 
>  data = {"math[pi]","AD['2']"}> 
>  for i,line in ipairs(data) do 
>>  s = getfield(line) 
>>  if s then 
>>    print(line .. " = " .. s) 
>>  else 
>>   print(line .. " = [variable not found]") 
>>  end 
>>  end 
math table: 0x10ee05100 
pi 3 
math[pi] = 42 
AD table: 0x10ee19ee0 
'2' 2 
AD['2'] = bar 

math[pi]가 변경되지 않습니다,하지만 getfield은 글로벌 맥락에서 파이를 해석하고 3 그렇게 math의 잘못된 필드가 반환됩니다 가져옵니다.

+0

무엇이 실패할까요? – shaun5

+0

"내가 말하는 취약성의 종류 ..."에 대한 부록을 참조하십시오. –

+0

실패하게 만드는 시나리오를 만들 수 없습니다. 나는 생각했다 : AD = {[1] = 'foo', [ '1'] = 'foobar', [ '2'] = 'bar'}는 그렇게 할 것이지만 여전히 작동한다. – shaun5

0

당신은 문자열 '1'"'2'"를 얻을 수 있습니다. 당신은 무엇이든 객체로 돌려 그것을 평가해야한다 : 문자열 (사용자 입력 또는 뭔가처럼)하지만 신뢰할 수없는 소스에서 온 경우가 임의 코드를 실행할 수 있기 때문에

v = v[loadstring('return ' .. w)()] 

이 작업을 수행하지 마십시오.

+0

v = v [w]를 코드로 바꿀 때 오류가 발생합니다 ... – shaun5

+0

@ shaun5이고 오류는 무엇입니까? –

+0

국부적으로'v '(아무 것도없는 가치)를 색인하는 것을 시도하십시오 – shaun5

관련 문제