隐藏用户 运行 脚本的标准输入数据?

Hide stdin data from user running script?

我正在 spoj.com 上构建一个问题。用户必须提交一个脚本,该脚本将预先附加我的代码,为他提供他必须使用的功能。此类模板:

def youmustusethis(maptask, reducetask):
  data = sys.stdin.readlines()
  return reduce(reducetask, map(maptask, data))

##### USER WRITES CODE BELOW #####
....

有趣的是:用户经常破解输出而不是解决问题。我预计人们会忽略该功能并直接读取标准输入并完全忽略我提供的 "framework" 来处理它。

有没有办法从脚本的下半部分隐藏标准输入数据,从而强制使用我的框架来处理它?

这似乎是一个奇怪的要求。你可能应该只写一个便条说 "don't access sys.stdin" 或类似的东西。

在我的脑海中,您可以关闭 sys.stdin 或重新分配它。 例如:

_stdin = sys.stdin
sys.stdin = None

[编辑:我觉得我应该提一下,这通常是个坏主意。]

您可以这样做:

import sys
try:
    import StringIO as io # python2
except ImportError:
    import io             # python3

# your functions go here

sys.stdin = io.StringIO()

如果您的用户尝试使用 stdin,这将使正常的文件操作不会失败,但也不会通过。但是,您的用户可能难以诊断。

比较:

def fails_loudly():
    """throws AttributeError"""
    sys.stdin = None
    return sys.stdin.read()

def fails_silently():
    """returns empty string"""
    sys.stdin = io.StringIO()
    return sys.stdin.read()

我找到了可能的解决方案。显然我可以向用户展示一个模板并预先附加一个不同的模板(略有不同)所以,我告诉用户 "use this":

def youmustusethis(maptask, reducetask):
  data = sys.stdin.readlines()
  return reduce(reducetask, map(maptask, data))

##### USER WRITES CODE BELOW #####

虽然我预先附加了类似的内容:

def youmustusethis(maptask, reducetask):
  DATA_48fsnk29s73kdhx7292k = sys.stdin.readlines()
  return reduce(reducetask, map(maptask, DATA_48fsnk29s73kdhx7292k))

##### USER WRITES CODE BELOW #####

请注意,根据 SPOJ 判断,代码是 运行,仅显示用户 AC/WA,没有标准输出或标准错误。除非用户能猜出变量名,否则很难找到。

我的建议是——不要。为了使这项工作正常进行,您需要考虑很多事情。考虑以下片段:

sys.stdin = open("/dev/stdin")

对于 ctypes,这可能会变得更加困难。我建议寻找某人已经创建的 sandboxing/restricted Python 环境,而不是试图混淆相当大的攻击媒介。我的猜测是 IRC 机器人的库应该已经正确地做到了这一点。