View Javadoc
1   package io.jawk;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * Jawk
6    * ჻჻჻჻჻჻
7    * Copyright (C) 2006 - 2026 MetricsHub
8    * ჻჻჻჻჻჻
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23   */
24  
25  import java.util.Collection;
26  import java.util.List;
27  import io.jawk.backend.AVM;
28  import io.jawk.backend.SandboxedAVM;
29  import io.jawk.ext.JawkExtension;
30  import io.jawk.util.AwkSettings;
31  import io.jawk.util.ScriptSource;
32  
33  /**
34   * {@link Awk} variant that enforces sandbox restrictions by delegating to the
35   * sandbox-specific tuple and runtime implementations.
36   */
37  public final class SandboxedAwk extends Awk {
38  
39  	/**
40  	 * Creates a sandboxed AWK instance with default settings and no extensions.
41  	 */
42  	public SandboxedAwk() {
43  		super();
44  	}
45  
46  	/**
47  	 * Creates a sandboxed AWK instance with the specified settings.
48  	 *
49  	 * @param settings behavioral configuration for this engine
50  	 */
51  	public SandboxedAwk(AwkSettings settings) {
52  		super(settings);
53  	}
54  
55  	/**
56  	 * Creates a sandboxed AWK instance with the supplied extensions.
57  	 *
58  	 * @param extensions Extension instances to register
59  	 */
60  	public SandboxedAwk(Collection<? extends JawkExtension> extensions) {
61  		super(extensions);
62  	}
63  
64  	/**
65  	 * Creates a sandboxed AWK instance with extensions and settings.
66  	 *
67  	 * @param extensions extension instances
68  	 * @param settings behavioral configuration for this engine
69  	 */
70  	public SandboxedAwk(Collection<? extends JawkExtension> extensions, AwkSettings settings) {
71  		super(extensions, settings);
72  	}
73  
74  	/**
75  	 * Creates a sandboxed AWK instance with the supplied extensions.
76  	 *
77  	 * @param extensions Extension instances to register
78  	 */
79  	@SafeVarargs
80  	public SandboxedAwk(JawkExtension... extensions) {
81  		super(extensions);
82  	}
83  
84  	@Override
85  	public AwkProgram compile(List<ScriptSource> scripts, boolean disableOptimizeParam) throws java.io.IOException {
86  		return compileProgram(scripts, disableOptimizeParam, new SandboxedCompiledAwkProgram());
87  	}
88  
89  	@Override
90  	public AwkExpression compileExpression(String expression, boolean disableOptimizeParam) throws java.io.IOException {
91  		return compileExpression(expression, disableOptimizeParam, new SandboxedCompiledAwkExpression());
92  	}
93  
94  	@Override
95  	public AVM createAvm() {
96  		return createAvm(getSettings());
97  	}
98  
99  	@Override
100 	public AVM createAvm(boolean profilingEnabled) {
101 		return createAvm(getSettings(), profilingEnabled);
102 	}
103 
104 	@Override
105 	protected AVM createAvm(AwkSettings settingsParam) {
106 		return createAvm(settingsParam, false);
107 	}
108 
109 	@Override
110 	protected AVM createAvm(AwkSettings settingsParam, boolean profilingEnabled) {
111 		return new SandboxedAVM(settingsParam, getExtensionInstances(), profilingEnabled);
112 	}
113 }
114 
115 final class SandboxedCompiledAwkProgram extends AwkProgram {
116 	private static final long serialVersionUID = 1L;
117 
118 	@Override
119 	public void printToFile(int numExprs, boolean append) {
120 		deny("Output redirection is disabled in sandbox mode");
121 	}
122 
123 	@Override
124 	public void printToPipe(int numExprs) {
125 		deny("Command execution through pipelines is disabled in sandbox mode");
126 	}
127 
128 	@Override
129 	public void printfToFile(int numExprs, boolean append) {
130 		deny("Output redirection is disabled in sandbox mode");
131 	}
132 
133 	@Override
134 	public void printfToPipe(int numExprs) {
135 		deny("Command execution through pipelines is disabled in sandbox mode");
136 	}
137 
138 	@Override
139 	public void system() {
140 		deny("system() is disabled in sandbox mode");
141 	}
142 
143 	@Override
144 	public void useAsCommandInput() {
145 		deny("Command execution through pipelines is disabled in sandbox mode");
146 	}
147 
148 	@Override
149 	public void useAsFileInput() {
150 		deny("Input redirection is disabled in sandbox mode");
151 	}
152 
153 	@Override
154 	public void assignARGC() {
155 		deny("Assigning to ARGC is disabled in sandbox mode");
156 	}
157 
158 	@Override
159 	public void argcOffset(int offset) {
160 		// no-op: keep argcOffset at NULL_OFFSET; AVM.getARGC() returns the
161 		// command-line argument count when ARGC is not materialized.
162 	}
163 
164 	@Override
165 	public void argvOffset(int offset) {
166 		// no-op: keep argvOffset at NULL_OFFSET; AVM.getARGV() returns a
167 		// synthetic AssocArray when ARGV is not materialized.
168 	}
169 
170 	private static void deny(String message) {
171 		throw new AwkSandboxException(message);
172 	}
173 }
174 
175 final class SandboxedCompiledAwkExpression extends AwkExpression {
176 	private static final long serialVersionUID = 1L;
177 
178 	@Override
179 	public void printToFile(int numExprs, boolean append) {
180 		deny("Output redirection is disabled in sandbox mode");
181 	}
182 
183 	@Override
184 	public void printToPipe(int numExprs) {
185 		deny("Command execution through pipelines is disabled in sandbox mode");
186 	}
187 
188 	@Override
189 	public void printfToFile(int numExprs, boolean append) {
190 		deny("Output redirection is disabled in sandbox mode");
191 	}
192 
193 	@Override
194 	public void printfToPipe(int numExprs) {
195 		deny("Command execution through pipelines is disabled in sandbox mode");
196 	}
197 
198 	@Override
199 	public void system() {
200 		deny("system() is disabled in sandbox mode");
201 	}
202 
203 	@Override
204 	public void useAsCommandInput() {
205 		deny("Command execution through pipelines is disabled in sandbox mode");
206 	}
207 
208 	@Override
209 	public void useAsFileInput() {
210 		deny("Input redirection is disabled in sandbox mode");
211 	}
212 
213 	@Override
214 	public void assignARGC() {
215 		deny("Assigning to ARGC is disabled in sandbox mode");
216 	}
217 
218 	@Override
219 	public void argcOffset(int offset) {
220 		// no-op: keep argcOffset at NULL_OFFSET; AVM.getARGC() returns the
221 		// command-line argument count when ARGC is not materialized.
222 	}
223 
224 	@Override
225 	public void argvOffset(int offset) {
226 		// no-op: keep argvOffset at NULL_OFFSET; AVM.getARGV() returns a
227 		// synthetic AssocArray when ARGV is not materialized.
228 	}
229 
230 	private static void deny(String message) {
231 		throw new AwkSandboxException(message);
232 	}
233 }