gpt4 book ai didi

module - 我什么时候应该在 Racket 中使用 `protect-out`?

转载 作者:行者123 更新时间:2023-12-04 12:03:11 25 4
gpt4 key购买 nike

Racket 提供 protect-out 防止模块导出与 eval (或解构的语法对象)一起使用,除非模块具有足够的权限(又名,具有 strong enough code inspector )。文档还提供了一个很好的例子来说明它的作用:

> (module nest racket
(provide num-eggs (protect-out num-chicks))
(define num-eggs 2)
(define num-chicks 3))
> (define weak-inspector (make-inspector (current-code-inspector)))
> (define (weak-eval x)
(parameterize ([current-code-inspector weak-inspector])
(define weak-ns (make-base-namespace))
(namespace-attach-module (current-namespace)
''nest
weak-ns)
(parameterize ([current-namespace weak-ns])
(namespace-require ''nest)
(eval x))))
> (require 'nest)
> (list num-eggs num-chicks)
'(2 3)
> (weak-eval 'num-eggs)
2
> (weak-eval 'num-chicks)
?: access disallowed by code inspector to protected variable
from module: 'nest
at: num-chicks

也就是说, eval有一个足够强大的代码检查器(因为它是在最初需要模块的同一范围内调用的),因此能够获得导出。但是, weak-eval没有,因为它获得了相同的模块实例,但使用较弱的检查器用于 eval ing。

我的问题是,我们什么时候应该使用 protect-out ?是否应该始终使用(或至少在可能的情况下)?或者有没有具体的工作流程 protect-out是为?

最佳答案

使用protect-out对于不安全的导出,其中不安全的意思是具有违反 Racket 语言或虚拟机规则的能力。特别是,经常有可能通过滥用不安全的功能使 Racket VM 崩溃。

不安全功能的示例:

  • unsafe-vector-set!或多或少允许您写入任意内存位置,可能会违反 GC 的不变量、Racket 在内存中的值表示的不变量等
  • unsafe-vector-ref看起来不那么危险,但你可以使用它来从闭包中提取自由变量的值,即使 Racket 语言不允许检查过程的实现
  • 大部分ffi/unsafe显然是不安全的

  • 这是一个不太明显的不安全过程示例:
    #lang racket
    (require ffi/unsafe ffi/unsafe/define)
    (define-ffi-definer define-c #f) ;; searches libc, etc
    (define-c fopen (_fun _path (_bytes = #"a") -> _pointer))
    (define-c fclose (_fun _pointer -> _void))
    (define-c fwrite (_fun _bytes _size _size _pointer -> _size))
    (define (append-to-file path buf)
    (define fp (fopen path))
    (unless fp (error "couldn't open file"))
    (fwrite buf (bytes-length buf) 1 fp)
    (fclose fp))
    (provide append-to-file)

    考虑 append-to-file程序。它是使用不安全特性(FFI)定义的,但 FFI 类型为 _path_bytes将拒绝错误的 Racket 值,因此使用 append-to-file 应该不可能使 Racket 崩溃. append-to-file程序仍然不安全(尽管可能不像 unsafe-vector-set! 那样具有灾难性的不安全性),因为它绕过了 Racket 的安全防护机制。该过程在另一个方面是不安全的,因为 fopenfwrite可以阻塞,并且 Racket 代码不应该阻塞。
    protect-out 提供了 Racket 核心库中的不安全操作.如果您使用它们来定义您自己的不安全操作,您应该使用 protect-out 提供派生的不安全操作。也。如果你使用不安全的特性来定义一个安全的特性,那么你可以正常提供(即不带 protect-out ),但首先要仔细考虑!

    如果您捕获特权代码检查器(直接或间接通过 #%variable-reference ),您还应该保护它,因为它可用于动态访问不安全的功能。

    目标是这样的:如果命名空间仅包含具有属性保护其不安全导出的模块,那么任何使用较弱代码检查器评估的附加代码都不应违反 Racket VM 的不变量(例如,使其崩溃,绕过安全防护检查等)。

    关于module - 我什么时候应该在 Racket 中使用 `protect-out`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51752449/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com