gpt4 book ai didi

java - 防止 JVM 写入 System.out 或从 System.in 读取

转载 作者:行者123 更新时间:2023-11-29 05:19:35 24 4
gpt4 key购买 nike

JVM 下有没有办法(暂时)阻止对 System.out、System.in 和 System.err 的完全访问?

创建一个完全不授予任何权限的空白策略后,我想在下面的函数中执行一些工作。 我希望对 System.out.println 等的调用失败,但它们没有。有什么我可以做的,还是我有点太控制狂了? p>

编辑 #1: 按照 MrPixelDream 的建议使用 System.setOut , 我将权限保持在最低限度以确保代码在 run() 内也不能调用 System.setOut或玩弄 java.io.FileDescriptor.out .

编辑#2:此外,由于流氓代码可以简单地执行 standardOutput.println , 我不想保留对 System.out 的引用周围并使用 java.io.FileDescriptor.out 将其设置回去.

// Create blank permissions that barely allow executing code
java.security.Permissions perm = new java.security.Permissions();

// CodeSource domain for which these permissions apply (all files)
java.security.CodeSource code = new java.security.CodeSource(new java.net.URL("file:/*"),
null);

// ProtectionDomain
java.security.ProtectionDomain domain = new java.security.ProtectionDomain(code, perm);

// AccessControlContext
java.security.ProtectionDomain[] domains = new java.security.ProtectionDomain[1];
domains[0] = domain;

java.security.AccessControlContext context =
new java.security.AccessControlContext(domains);

// DON'T keep reference to standard output, it could be used directly
// PrintStream standardOut = System.out;

// Redirect output to dummy stream
System.setIn(new ByteArrayInputStream(new byte[0]));
System.setOut(new PrintStream(new ByteArrayOutputStream()));
System.setErr(new PrintStream(new ByteArrayOutputStream()));

// Do an action, subject to the given security context
java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {

public Void run() {

// Do some work, side effects and all, but no I/O whatsoever
System.out.println("Will not print !");

// Try to fool around System.out with direct access from file descriptors (0, 1, 2)
java.io.PrintStream myOut =
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out));

// Missing permission java.lang.RuntimePermission "setIO"
// Will throw java.security.AccessControlException
System.setOut(myOut);

// Missing permission java.lang.RuntimePermission "writeFileDescriptor"
myOut.println("Will throw java.security.AccessControlException !");

}

}, context);

// Now set back the old streams to have output again
System.setIn(new java.io.FileInputStream(java.io.FileDescriptor.in));
System.setOut(
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
System.setErr(
new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));

最佳答案

Elliott Frisch 的答案可以解决问题,但您无法在完成后收到输出。如果您打算暂时将输出静音,请使用此代码:

public class RedirectedOutput {

public static void main(String[] args) {
// Save the old output stream to have the chance to set it back later
InputStream standardIn = System.in;
PrintStream standardOut = System.out;
PrintStream standardErr = System.err;

// Set useless streams
System.setIn(new ByteArrayInputStream(new byte[0]));
System.setOut(new PrintStream(new ByteArrayOutputStream()));
System.setErr(new PrintStream(new ByteArrayOutputStream()));

// Will not be shown
System.out.println("Hello World");

// Now set back the old streams to have output again
System.setIn(standardIn);
System.setOut(standardOut);
System.setErr(standardErr);

// Will be shown again
System.out.println("Finally we got the Hello");
}

}

您可以尝试这个应该可以完全运行的示例。它应该是不言自明的。您正在使用 setIn()setOut()setErr() 来更改流并且您在设置之前保存它回来。

但如果您不需要任何输出,您最好使用 Elliott 的代码,因为我猜它更适合资源。

关于java - 防止 JVM 写入 System.out 或从 System.in 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25316058/

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