2010-11-17 20 views
14

json2.js yêu cầu nghiêm ngặt tất cả các khóa đối tượng phải được trích dẫn kép. Tuy nhiên, trong cú pháp Javascript {"foo":"bar"} tương đương với {foo:"bar"}.Phân tích cú pháp một chuỗi JSON một cách an toàn với các phím không được kiểm soát

Tôi có một vùng văn bản chấp nhận đầu vào JSON từ người dùng và muốn "giảm bớt" hạn chế về việc trích dẫn kép các phím. Tôi đã xem xét cách json2.js xác nhận hợp lệ một chuỗi JSON trong bốn giai đoạn trước khi nó evals nó. Tôi đã có thể thêm một giai đoạn thứ 5 để cho phép các phím không được kiểm soát và muốn biết liệu có bất kỳ tác động bảo mật nào đối với logic này hay không.

var data = '{name:"hello", age:"23"}'; 

// Make sure the incoming data is actual JSON 
// Logic borrowed from http://json.org/json2.js 
if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") 
    .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") 
    .replace(/(?:^|:|,)(?:\s*\[)+/g, ":") // EDITED: allow key:[array] by replacing with safe char ":" 
    /** everything up to this point is json2.js **/ 

    /** this is the 5th stage where it accepts unquoted keys **/   
    .replace(/\w+\s*\:/g, ":"))) { // EDITED: allow any alphanumeric key 

    console.log((new Function("return " + data))()); 
} 
else { 
    throw("Invalid JSON: " + data); 
} 
+4

Bạn giả sử một đối tượng JavaScript Literal tương đương với JSON, nó không phải là. – Stephen

+6

'{name:" Joe "}' là Javascript hợp lệ, nhưng nó là _invalid_ JSON. Ngoài ra, bạn không muốn hack 'json2.js' vì nó chỉ phản ánh cách trình duyệt hỗ trợ JSON gốc của trình duyệt hoạt động. Trong Chrome, ví dụ, 'JSON.parse()' mà không có 'json2.js' sẽ bị sặc trên đó. Nhưng tệ hơn là 'json2.js' sẽ không tải bất cứ thứ gì nếu trình duyệt không hỗ trợ JSON gốc. Vì vậy, bạn sẽ ở trong một tình huống mà các trình duyệt có hỗ trợ JSON gốc không bao giờ thấy hack này, bởi vì nó sử dụng mã gốc để phân tích cú pháp thay thế. –

+0

@Stephen Bạn nói đúng. Có lẽ tôi nên thuật lại câu hỏi là "Phân tích cú pháp đối tượng JavaScript một cách an toàn và chuyển đổi sang JSON"? – daepark

Trả lời

0

JSON không cho phép khóa không được kiểm soát. JSON là tập con của ký hiệu JavaScript và không bao gồm các khóa không được kiểm soát. Việc chuyển các khóa không được kiểm soát tới bất kỳ trình phân tích cú pháp JSON nào có khả năng sẽ bị lỗi hoặc trả về các kết quả "không mong muốn".

Hope this helps

+3

Đúng về JSON tất nhiên, nhưng JavaScript cho phép các phím không được kiểm soát trong các đối tượng literals. Nó chỉ là một chút vấn đề khi bạn không thể sử dụng dấu gạch ngang hoặc từ dành riêng mà không có dấu ngoặc kép. Tôi nghĩ người hỏi đã biết điều này rồi, tuy nhiên. – JAL

3
data.replace(/(['"])?([a-zA-Z0-9]+)(['"])?:/g, '"$2":'); 

Điều đó sẽ thay thế bất kỳ dấu nháy đơn vào tên tham số, và thêm bất kỳ đang thiếu.

+5

Điều này dường như hoạt động. Ngoại trừ bạn không thể xử lý dấu gạch dưới. Đây là một regex được cập nhật: 'hash.replace (/ (['"])? ([A-zA-Z0-9 _] +) ([' "])?:/G, '" $ 2 ":');' –

+0

touche, cảm ơn bạn là một người giám sát –

+4

Câu trả lời này là hoàn hảo. Hãy thử '{a: ['b', 'c']}' hoặc '{a:" Lưu ý: đã xảy ra sự cố. "}' – powerboy

1

Tôi nghĩ sẽ hữu ích khi có các trường hợp thử nghiệm thực tế để loại bỏ mọi vấn đề với việc triển khai này. Tôi đã thêm một dự án github gọi là JSOL với một số thử nghiệm. Vui lòng điền miễn phí để thêm vào và tìm sự cố. Cảm ơn.

https://github.com/daepark/JSOL

Các vấn đề liên quan