2016-07-25 16 views
5

Ví dụ: tôi đã tải một tập lệnh trên một số trang web và tôi muốn biết liệu JSON.parse/stringify có phải là bản vá của khỉ hay không.Có cách nào để kiểm tra xem hàm Javascript gốc có bị vá không?

tôi nhận thấy rằng nếu tôi sử dụng toString về chức năng trong Chrome/FF, JSON.stringify.toString, sau đó tôi nhận được trở lại:

function stringify() { 
    [native code] 
} 

Câu hỏi của tôi là bạn có nghĩ rằng đây là một cách tốt để xác minh nếu một chức năng là khỉ vá? Cũng rất muốn nghe về bất kỳ phương pháp tiếp cận khác cho vấn đề này.

+2

Có thể bạn có thể chạy tập lệnh của riêng mình trong WebWorker và so sánh chức năng từ bên trong công nhân với chức năng từ trang chính. – Buzzy

Trả lời

4

Có, đây là cách thực tế duy nhất để kiểm tra xem chức năng gốc có bị ghi đè hay không.

const isNative = fn => !!fn.toString().match(/\[native code\]/) 

console.log(isNative(JSON.stringify)); 

Một giải pháp mạnh mẽ hơn có thể sử dụng Function.prototype.toString() thay vì gọi trực tiếp của fn.toString(), nhưng cả hai đều monkeypatchable là tốt. Những niềm vui của JavaScript :)

4

Người ta có thể dễ dàng giả JSON.stringify.toString

JSON.stringify = function() {} 
JSON.stringify.toString = function() {return 'ha-ha'} 

console.log(JSON.stringify); //ha-ha 

cách mạnh mẽ hơn một chút sẽ được sử dụng Function.prototype.toString

Function.prototype.toString.call(JSON.stringify) 

Nhưng thực sự monkeypatcher xấu có thể vá Function.prototype.toString cũng :)

3

Thông số kỹ thuật (http://www.ecma-international.org/ecma-262/7.0/index.html#sec-function.prototype.tostring) không chỉ định chuỗi chính xác được trả lại cho functi được xây dựng vào lúc:

19.2.3.5 Function.prototype.toString

Khi phương thức toString được gọi là trên một func đối tượng, bước sau đây được thực hiện:

Nếu func là một chức năng ràng buộc đối tượng kỳ lạ , sau đó Trả lại một phụ thuộc vào triển khai thực hiện Biểu thị mã nguồn chuỗi của func. Đại diện phải tuân theo các quy tắc dưới đây. Nó là thực hiện phụ thuộc cho dù các đại diện bao gồm ràng buộc thông tin chức năng hoặc thông tin về chức năng mục tiêu. Nếu Loại (func) là đối tượng và có thể là đối tượng hàm dựng sẵn hoặc có khe nội bộ [[ECMAScriptCode]], sau đó trả về biểu diễn mã nguồn chuỗi phụ thuộc triển khai thực hiện của func. Đại diện phải tuân theo các quy tắc dưới đây. Ném ngoại lệ TypeError . Yêu cầu toString Đại diện:

Các đại diện chuỗi phải có cú pháp của một FunctionDeclaration , FunctionExpression, GeneratorDeclaration, GeneratorExpression, ClassDeclaration, ClassExpression, ArrowFunction, MethodDefinition, hoặc GeneratorMethod phụ thuộc vào đặc điểm thực tế của đối tượng. Việc sử dụng và sắp xếp không gian trắng, các thiết bị đầu cuối dòng và dấu chấm phẩy trong chuỗi đại diện là phụ thuộc vào triển khai.Nếu đối tượng được xác định bằng cách sử dụng mã ECMAScript và biểu diễn chuỗi trả về không ở dạng MethodDefinition hoặc GeneratorMethod thì biểu diễn phải là sao cho chuỗi được đánh giá, sử dụng eval trong ngữ cảnh từ vựng tương đương với ngữ cảnh từ vựng được sử dụng để tạo đối tượng gốc, nó sẽ dẫn đến một đối tượng tương đương với hàm mới. Trong trường hợp trường hợp mã nguồn trả lại không được tự do đề cập đến bất kỳ biến số nào không được đề cập một cách tự do bởi mã nguồn của hàm ban đầu, ngay cả khi các tên "phụ" này ban đầu nằm trong phạm vi. Nếu việc triển khai không thể tạo chuỗi mã nguồn đáp ứng được các tiêu chí này sau đó, nó phải trả về một chuỗi mà eval sẽ ném ngoại lệ SyntaxError.

Vì vậy, việc kiểm tra [Native Code] có thể có hoặc không hoạt động tùy thuộc vào thông dịch viên. Hơn nữa, việc triển khai cũng có thể triển khai các hàm dựng sẵn như mã javascript bình thường.

Vì vậy, trong câu trả lời cho câu hỏi của bạn, bạn không thể xác định, là một cách được chỉ định Javascript cho dù hàm dựng sẵn đã được vá khỉ hay chưa.

Điều đó có vẻ như Chrome và Firefox đều trả về chuỗi [Native Code] tùy thuộc vào việc xác minh các triển khai khác có thể là giải pháp thực dụng.

+0

* "Hơn nữa, việc triển khai cũng có thể triển khai các chức năng dựng sẵn như mã javascript bình thường." * Điều này có lẽ không phải là vấn đề. 'Lời hứa' của V8 được thực hiện bằng JavaScript] (https://github.com/v8/v8/blob/986814218b907cbac244a3624362ee9351f6badb/src/js/promise.js) và 'Promise.toString()' vẫn có' [mã gốc] ' trong đó. – noppa

+0

Thú vị .... – HBP

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