我在spoj.com上构建了一个问题。用户必须提交一个脚本,该脚本将预先附加我的代码,该代码将为他提供他必须使用的功能。这种模板:
def youmustusethis(maptask, reducetask):
data = sys.stdin.readlines()
return reduce(reducetask, map(maptask, data))
##### USER WRITES CODE BELOW #####
....
有趣的是:用户经常乱砍输出而不是解决问题。我预计人们会忽略功能并直接读取stdin并完全忽略"框架"我提供。
有没有办法以一种强制使用我的框架来处理它的方式隐藏脚本下半部分的stdin数据?
答案 0 :(得分:2)
这似乎是一个奇怪的要求。您应该只写一个说“不要访问sys.stdin”或类似的东西。
离开我的头顶,你可以关闭sys.stdin,或者重新分配它。 例如:
_stdin = sys.stdin
sys.stdin = None
[编辑:我觉得我应该提一下,这通常是一个坏主意。]
答案 1 :(得分:2)
您可以执行以下操作:
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()
答案 2 :(得分:1)
我的建议是 - 不要。为了使这项工作正常,您需要考虑许多事项。请考虑以下代码段:
sys.stdin = open("/dev/stdin")
使用ctypes
,这可能会变得更加困难。我建议寻找有人已经创建的沙盒/受限制的Python环境,而不是试图混淆一个相当大的攻击向量。我的猜测是IRC机器人的库应该已经正确地做到了这一点。
答案 3 :(得分:0)
我找到了一个可能的解决方案。显然我可以向用户显示一个模板并预先附加一个不同的模板(略有不同)所以,我告诉用户“使用此”:
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且没有stdout或stderr。除非用户可以猜出变量名称,否则他能够找到它是值得怀疑的。