mirror of
https://github.com/enso-org/enso.git
synced 2025-01-03 19:03:22 +03:00
Ensure disable private check cmd line option disables runtime private access checks (#10034)
Ensure that `--disable-private-check` cmd line option disables the runtime private access checks as well.
This commit is contained in:
parent
91a2afb098
commit
ba2787c4d2
@ -30,6 +30,7 @@ import org.enso.pkg.QualifiedName;
|
|||||||
import org.enso.polyglot.PolyglotContext;
|
import org.enso.polyglot.PolyglotContext;
|
||||||
import org.enso.polyglot.RuntimeOptions;
|
import org.enso.polyglot.RuntimeOptions;
|
||||||
import org.graalvm.polyglot.Context;
|
import org.graalvm.polyglot.Context;
|
||||||
|
import org.graalvm.polyglot.Context.Builder;
|
||||||
import org.graalvm.polyglot.Language;
|
import org.graalvm.polyglot.Language;
|
||||||
import org.graalvm.polyglot.Source;
|
import org.graalvm.polyglot.Source;
|
||||||
import org.graalvm.polyglot.Value;
|
import org.graalvm.polyglot.Value;
|
||||||
@ -227,14 +228,16 @@ prefer-local-libraries: true
|
|||||||
* Tests running the project located in the given {@code projDir}. Is equal to running {@code enso
|
* Tests running the project located in the given {@code projDir}. Is equal to running {@code enso
|
||||||
* --run <projDir>}.
|
* --run <projDir>}.
|
||||||
*
|
*
|
||||||
|
* @param ctxBuilder A context builder that might be initialized with some specific options.
|
||||||
* @param projDir Root directory of the project.
|
* @param projDir Root directory of the project.
|
||||||
* @param resultConsumer Any action that is to be evaluated on the result of running the {@code
|
* @param resultConsumer Any action that is to be evaluated on the result of running the {@code
|
||||||
* main} method
|
* main} method
|
||||||
*/
|
*/
|
||||||
protected void testProjectRun(Path projDir, Consumer<Value> resultConsumer) {
|
protected void testProjectRun(
|
||||||
|
Context.Builder ctxBuilder, Path projDir, Consumer<Value> resultConsumer) {
|
||||||
assert projDir.toFile().exists() && projDir.toFile().isDirectory();
|
assert projDir.toFile().exists() && projDir.toFile().isDirectory();
|
||||||
try (var ctx =
|
try (var ctx =
|
||||||
defaultContextBuilder()
|
ctxBuilder
|
||||||
.option(RuntimeOptions.PROJECT_ROOT, projDir.toAbsolutePath().toString())
|
.option(RuntimeOptions.PROJECT_ROOT, projDir.toAbsolutePath().toString())
|
||||||
.option(RuntimeOptions.STRICT_ERRORS, "true")
|
.option(RuntimeOptions.STRICT_ERRORS, "true")
|
||||||
.option(RuntimeOptions.DISABLE_IR_CACHES, "true")
|
.option(RuntimeOptions.DISABLE_IR_CACHES, "true")
|
||||||
@ -249,6 +252,17 @@ prefer-local-libraries: true
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a wrapper for {@link TestBase#testProjectRun(Builder, Path, Consumer)}.
|
||||||
|
*
|
||||||
|
* @param projDir Root directory of the project.
|
||||||
|
* @param resultConsumer Any action that is to be evaluated on the result of running the {@code
|
||||||
|
* main} method
|
||||||
|
*/
|
||||||
|
protected void testProjectRun(Path projDir, Consumer<Value> resultConsumer) {
|
||||||
|
testProjectRun(defaultContextBuilder(), projDir, resultConsumer);
|
||||||
|
}
|
||||||
|
|
||||||
/** A simple structure corresponding to an Enso module. */
|
/** A simple structure corresponding to an Enso module. */
|
||||||
public record SourceModule(QualifiedName name, String code) {}
|
public record SourceModule(QualifiedName name, String code) {}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package org.enso.interpreter.test;
|
package org.enso.interpreter.test.privateaccess;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
@ -10,6 +10,7 @@ import static org.junit.Assert.fail;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.enso.interpreter.test.TestBase;
|
||||||
import org.enso.interpreter.util.ScalaConversions;
|
import org.enso.interpreter.util.ScalaConversions;
|
||||||
import org.enso.polyglot.PolyglotContext;
|
import org.enso.polyglot.PolyglotContext;
|
||||||
import org.enso.polyglot.RuntimeOptions;
|
import org.enso.polyglot.RuntimeOptions;
|
||||||
@ -47,20 +48,13 @@ public class PrivateAccessTest extends TestBase {
|
|||||||
main = My_Type.Cons 42
|
main = My_Type.Cons 42
|
||||||
""";
|
""";
|
||||||
var projDir = createProject("My_Project", mainSrc, tempFolder);
|
var projDir = createProject("My_Project", mainSrc, tempFolder);
|
||||||
var mainSrcPath = projDir.resolve("src").resolve("Main.enso");
|
testProjectRun(
|
||||||
try (var ctx =
|
projDir,
|
||||||
defaultContextBuilder()
|
res -> {
|
||||||
.option(RuntimeOptions.PROJECT_ROOT, projDir.toAbsolutePath().toString())
|
|
||||||
.build()) {
|
|
||||||
var polyCtx = new PolyglotContext(ctx);
|
|
||||||
var mainMod = polyCtx.evalModule(mainSrcPath.toFile());
|
|
||||||
var assocType = mainMod.getAssociatedType();
|
|
||||||
var mainMethod = mainMod.getMethod(assocType, "main").get();
|
|
||||||
var res = mainMethod.execute();
|
|
||||||
assertThat(res.hasMember("data"), is(false));
|
assertThat(res.hasMember("data"), is(false));
|
||||||
assertThat(res.canInvokeMember("data"), is(false));
|
assertThat(res.canInvokeMember("data"), is(false));
|
||||||
assertThat(res.getMember("data"), is(nullValue()));
|
assertThat(res.getMember("data"), is(nullValue()));
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -127,19 +121,12 @@ public class PrivateAccessTest extends TestBase {
|
|||||||
_ -> 0
|
_ -> 0
|
||||||
""";
|
""";
|
||||||
var projDir = createProject("My_Project", mainSrc, tempFolder);
|
var projDir = createProject("My_Project", mainSrc, tempFolder);
|
||||||
var mainSrcPath = projDir.resolve("src").resolve("Main.enso");
|
testProjectRun(
|
||||||
try (var ctx =
|
projDir,
|
||||||
defaultContextBuilder()
|
res -> {
|
||||||
.option(RuntimeOptions.PROJECT_ROOT, projDir.toAbsolutePath().toString())
|
|
||||||
.build()) {
|
|
||||||
var polyCtx = new PolyglotContext(ctx);
|
|
||||||
var mainMod = polyCtx.evalModule(mainSrcPath.toFile());
|
|
||||||
var assocType = mainMod.getAssociatedType();
|
|
||||||
var mainMethod = mainMod.getMethod(assocType, "main").get();
|
|
||||||
var res = mainMethod.execute();
|
|
||||||
assertThat(res.isNumber(), is(true));
|
assertThat(res.isNumber(), is(true));
|
||||||
assertThat(res.asInt(), is(42));
|
assertThat(res.asInt(), is(42));
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests that pattern matching on private constructors fails in compilation. */
|
/** Tests that pattern matching on private constructors fails in compilation. */
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.enso.interpreter.test.privateaccess;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.enso.interpreter.test.TestBase;
|
||||||
|
import org.enso.polyglot.RuntimeOptions;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
|
||||||
|
public class PrivateCheckDisabledTest extends TestBase {
|
||||||
|
@Rule public TemporaryFolder tempFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void privateCtorCanBeAccessedWhenPrivateCheckIsDisabled() throws IOException {
|
||||||
|
var libSrc = """
|
||||||
|
type T
|
||||||
|
private Cons data
|
||||||
|
""";
|
||||||
|
createProject("Lib", libSrc, tempFolder);
|
||||||
|
var mainSrc =
|
||||||
|
"""
|
||||||
|
from local.Lib import T
|
||||||
|
main =
|
||||||
|
obj = T.Cons 42
|
||||||
|
obj.data
|
||||||
|
""";
|
||||||
|
var mainDir = createProject("Main", mainSrc, tempFolder);
|
||||||
|
var ctxBuilder = defaultContextBuilder().option(RuntimeOptions.DISABLE_PRIVATE_CHECK, "true");
|
||||||
|
testProjectRun(
|
||||||
|
ctxBuilder,
|
||||||
|
mainDir,
|
||||||
|
res -> {
|
||||||
|
assertThat(res.isNumber(), is(true));
|
||||||
|
assertThat(res.asInt(), is(42));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package org.enso.interpreter.node.callable.dispatch;
|
package org.enso.interpreter.node.callable.dispatch;
|
||||||
|
|
||||||
|
import com.oracle.truffle.api.CompilerAsserts;
|
||||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||||
import com.oracle.truffle.api.TruffleFile;
|
import com.oracle.truffle.api.TruffleFile;
|
||||||
import com.oracle.truffle.api.dsl.Cached;
|
import com.oracle.truffle.api.dsl.Cached;
|
||||||
@ -113,6 +114,16 @@ public abstract class InvokeFunctionNode extends BaseNode {
|
|||||||
return new PanicException(err, this);
|
return new PanicException(err, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensureFunctionIsAccessible(Function function, FunctionSchema functionSchema) {
|
||||||
|
var isPrivateCheckDisabled = getContext().isPrivateCheckDisabled();
|
||||||
|
CompilerAsserts.compilationConstant(isPrivateCheckDisabled);
|
||||||
|
if (!isPrivateCheckDisabled
|
||||||
|
&& functionSchema.isProjectPrivate()
|
||||||
|
&& !isInSameProject(function)) {
|
||||||
|
throw makePrivateAccessPanic(function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Specialization(
|
@Specialization(
|
||||||
guards = {"!getContext().isInlineCachingDisabled()", "function.getSchema() == cachedSchema"},
|
guards = {"!getContext().isInlineCachingDisabled()", "function.getSchema() == cachedSchema"},
|
||||||
limit = Constants.CacheSizes.ARGUMENT_SORTER_NODE)
|
limit = Constants.CacheSizes.ARGUMENT_SORTER_NODE)
|
||||||
@ -130,9 +141,7 @@ public abstract class InvokeFunctionNode extends BaseNode {
|
|||||||
"build(argumentMapping, getDefaultsExecutionMode(), getArgumentsExecutionMode(),"
|
"build(argumentMapping, getDefaultsExecutionMode(), getArgumentsExecutionMode(),"
|
||||||
+ " getTailStatus())")
|
+ " getTailStatus())")
|
||||||
CurryNode curryNode) {
|
CurryNode curryNode) {
|
||||||
if (cachedSchema.isProjectPrivate() && !isInSameProject(function)) {
|
ensureFunctionIsAccessible(function, cachedSchema);
|
||||||
throw makePrivateAccessPanic(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArgumentSorterNode.MappedArguments mappedArguments =
|
ArgumentSorterNode.MappedArguments mappedArguments =
|
||||||
mappingNode.execute(callerFrame, function, state, arguments);
|
mappingNode.execute(callerFrame, function, state, arguments);
|
||||||
@ -174,9 +183,7 @@ public abstract class InvokeFunctionNode extends BaseNode {
|
|||||||
Object[] arguments,
|
Object[] arguments,
|
||||||
@Cached IndirectArgumentSorterNode mappingNode,
|
@Cached IndirectArgumentSorterNode mappingNode,
|
||||||
@Cached IndirectCurryNode curryNode) {
|
@Cached IndirectCurryNode curryNode) {
|
||||||
if (function.getSchema().isProjectPrivate() && !isInSameProject(function)) {
|
ensureFunctionIsAccessible(function, function.getSchema());
|
||||||
throw makePrivateAccessPanic(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallArgumentInfo.ArgumentMapping argumentMapping =
|
CallArgumentInfo.ArgumentMapping argumentMapping =
|
||||||
CallArgumentInfo.ArgumentMappingBuilder.generate(function.getSchema(), getSchema());
|
CallArgumentInfo.ArgumentMappingBuilder.generate(function.getSchema(), getSchema());
|
||||||
|
Loading…
Reference in New Issue
Block a user