2013-05-01 6 views
1

CentOS 6.4의 RVM에서 Ruby 1.9.3-p392으로 JSON을 구문 분석 할 때 이상한 문제가 발생합니다. 임베디드 객체를 적절한 Ruby 클래스로 디코딩하는 대신 객체를 해시로로드하는 것입니다. Ruby 1.9.3-p194에서 제대로 작동합니다.Ruby 1.9.3 JSON 구문 분석

: 나는 Ruby 1.9.3-p392에서 같은 조각을 실행하면

#<TestMe:0x00000001c877f0> 

, 그것은 다음과 같은 출력 :

require 'json' 

class TestMe 
    attr_accessor :me 
    def initialize(option_hash = nil) 
     if option_hash 
      @me = option_hash['me'] 
     end 
     @me ||= "Hello" 
    end 

    def to_json(*a) 
     { 
      JSON.create_id => self.class.name, 
      'data' => { 
       "me" => @me 
      } 
     }.to_json(*a) 
    end 

    def self.json_create(o) 
     new(o['data']) 
    end 
end 

t = TestMe.new 
t.me = "foo" 
t2 = JSON.parse(t.to_json) 
puts t2 

내가 Ruby 1.9.3-p194에서이 작업을 실행하면 다음과 같은 출력 :

는 다음과 같은 샘플을 채취

{"json_class"=>"TestMe", "data"=>{"me"=>"foo"}} 

p194의 동작 내가 이고 문서가 암시하는 내용이 무엇입니까? p392 JSON 데이터를 올바르게 파싱하지 않는 이유는 무엇입니까?

+1

2.0.0에서도 p392 동작이 발생하므로 의도 한 변경 사항을 적용해야합니다. – Linuxios

+0

이 변경 사항을 설명하는 설명서에서 명백한 내용을 놓쳤습니까? 제 말은 ... 이전 버전과 호환되지 않습니다 ... – organicveggie

+1

이것은 최근의 [보안 권고] (https://support.cloud.engineyard.com/entries/23143553-Security-Fabruary-11-11-2013-Rails)와 관련이 있습니다. JSON-Vulnerabilities) 및 Rails에 대한 패치를 제공합니다. 이것은 매우 신중한 변화 일 수 있습니다. 중립적 인 데이터 전용 전송 메소드로 생각되었던 것에 기본적으로 Ruby 객체의 임의적 인 인스턴스화를 허용하는 것은 결코 좋은 생각이 아닙니다. – tadman

답변

1

아직도/왜 변경되었는지는 확실하지 않지만 해결 방법을 찾았습니다. 기본적으로 JSON.parse을 호출하는 대신 Parser 개체를 만들고 :create_additions 옵션을 전달해야합니다.

예 :

다른 사람이 언급 한 것처럼
p = JSON::Parser.new(json_string, {:create_additions => true}) 
result = p.parse 
0

JSON 자체가 해시를 반환합니다. 추가 기능을 제공하는 확장 기능이 있습니다. 사용해보십시오 :

require 'json' 
require 'json/add/core' 

나는 자동으로 확장을로드하지만이 JSON 사양과 비교를 위해 떨어졌다 지난 루비 JSON의 한 지점에서 생각합니다.

"add/core"는 객체를 기반으로하는 일부 to_json 메소드를 포함하며 사용자 정의 객체를 복구하는 기능을 추가 할 수 있습니다. JSON을 통해 정규 표현식을 전달하는 비슷한 상황이 발생하여 해결되었습니다.

내 컴퓨터 근처에 있지 않아 확인되지 않았지만 도움이 될 수 있습니다.

+0

JSON 데이터에서 임의의 Ruby 구조를로드하는 것은 완전히 제멋대로이기 때문에 삭제 된 것 같습니다. – tadman

+0

100 % 동의합니다. 'to_h' 메소드를 추가하여 와이어를 가로 지르는 클래스에 대한 해시를 만든 다음 해시를 사용하여 반대쪽에있는 객체를 다시 생성하도록'initialize'를 설정합니다. –

1

, 그것은 JSON 객체 unmarshelled있는 방법에 대한 최근의 변화처럼 들린다. 나는 매우 비슷한 이슈 here을 만났고 훌륭한 답을 얻었다.

+0

아. 매우 도움이됩니다. 지금 나 한테 훨씬 더 의미가있어. – organicveggie