From 862034b6c158545665a21caad44df4bdb08c7299 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Tue, 4 Oct 2016 02:05:52 +0900 Subject: [PATCH] =?UTF-8?q?Schr=C3=B6dinger's=20file:=20it's=20superpositi?= =?UTF-8?q?on=20between=20existent=20and=20nonexistent,=20file=20and=20dir?= =?UTF-8?q?ectory.=20Tried=20java.nio.file=20but=20it=20seems=20it's=20jus?= =?UTF-8?q?t=20Java=20that=20is=20broken=20like=20vittup=C3=A4=C3=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Former-commit-id: ec938b81d8c4a1385295846b7b3d5178652d93ad Former-commit-id: 0ff4806c81c94ec5a126894f8d41ca6891bcb1d2 --- src/net/torvald/terrarum/StateVTTest.kt | 4 +- .../computer/BaseTerrarumComputer.kt | 18 ++-- .../virtualcomputer/luaapi/Filesystem.kt | 93 ++++++++++--------- .../terrarum/virtualcomputer/luaapi/Input.kt | 1 + .../terrarum/virtualcomputer/luaapi/Term.kt | 1 + 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/net/torvald/terrarum/StateVTTest.kt b/src/net/torvald/terrarum/StateVTTest.kt index 1f238d9fa..fbeb9607a 100644 --- a/src/net/torvald/terrarum/StateVTTest.kt +++ b/src/net/torvald/terrarum/StateVTTest.kt @@ -21,8 +21,8 @@ class StateVTTest : BasicGameState() { // HiRes: 100x64, LoRes: 80x25 val computerInside = BaseTerrarumComputer(8) - val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 80, 25, - computerInside, colour = false, hires = false) + val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 100, 64, + computerInside, colour = true, hires = true) val vtUI = Image(vt.displayW, vt.displayH) diff --git a/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt b/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt index 04ef6dd8c..a538ddec3 100644 --- a/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt +++ b/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt @@ -91,12 +91,12 @@ class BaseTerrarumComputer(peripheralSlots: Int) { computerValue["processor"] = -1 // do. // as in "dev/hda"; refers hard disk drive (and no partitioning) - computerValue["hda"] = "testhda" // 'UUID rendered as String' or "none" - computerValue["hdb"] = "none" + computerValue["hda"] = "uuid_testhda" // 'UUID rendered as String' or "none" + computerValue["hdb"] = "uuid_testhdb" computerValue["hdc"] = "none" computerValue["hdd"] = "none" // as in "dev/fd1"; refers floppy disk drive - computerValue["fd1"] = "none" + computerValue["fd1"] = "uuid_testfd1" computerValue["fd2"] = "none" computerValue["fd3"] = "none" computerValue["fd4"] = "none" @@ -159,7 +159,7 @@ class BaseTerrarumComputer(peripheralSlots: Int) { // secure the sandbox - luaJ_globals["io"] = LuaValue.NIL + //luaJ_globals["io"] = LuaValue.NIL // dubug should be sandboxed in BOOT.lua (use OpenComputers code) //val sethook = luaJ_globals["debug"]["sethook"] //luaJ_globals["debug"] = LuaValue.NIL @@ -207,12 +207,13 @@ class BaseTerrarumComputer(peripheralSlots: Int) { unsetThreadRun() } - driveBeepQueueManager(delta) } - - if (isHalted) { + if (!isHalted) { + driveBeepQueueManager(delta) + } + else { currentExecutionThread.interrupt() } } @@ -326,7 +327,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) { // complete emitTone queue if (beepCursor >= beepQueue.size) { clearBeepQueue() - if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear") } // actually play queue @@ -350,6 +350,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) { beepQueueLineExecTimer = 0 //AL.destroy() + + if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear") } fun enqueueBeep(duration: Int, freq: Double) { diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt index 8fda644f3..0f5ee2a84 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt @@ -10,6 +10,7 @@ import net.torvald.terrarum.virtualcomputer.luaapi.Term.Companion.checkIBM437 import java.io.* import java.nio.file.Files import java.nio.file.Path +import java.nio.file.Paths import java.util.* /** @@ -20,7 +21,9 @@ import java.util.* * Created by minjaesong on 16-09-17. * * - * NOTE: Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible! + * NOTES: + * Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible! + * Use .absoluteFile whenever possible; there's fuckin oddity! (http://bugs.java.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097) */ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { @@ -40,7 +43,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { globals["fs"]["concat"] = ConcatPath(computer) // OC compliant globals["fs"]["open"] = OpenFile(computer) //CC compliant globals["fs"]["parent"] = GetParentDir(computer) - // fs.dofile defined in ROMLIB + // fs.dofile defined in BOOT // fs.fetchText defined in ROMLIB } @@ -48,29 +51,34 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { fun ensurePathSanity(path: LuaValue) { if (path.checkIBM437().contains(Regex("""\.\."""))) throw LuaError("'..' on path is not supported.") + if (!isValidFilename(path.checkIBM437())) + throw IOException("path contains invalid characters") } val isCaseInsensitive: Boolean - get() { - // TODO add: force case insensitive in config - try { - val uuid = UUID.randomUUID().toString() - val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox") - val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX") - // This should NEVER happen but could also lead to VERY weird bugs, so we - // make sure the files don't exist. - lowerCase.exists() && lowerCase.delete() - upperCase.exists() && upperCase.delete() - lowerCase.createNewFile() - val insensitive = upperCase.exists() - lowerCase.delete() - return insensitive - } - catch (e: IOException) { - println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.") - return true - } + + init { + try { + val uuid = UUID.randomUUID().toString() + val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox") + val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX") + // This should NEVER happen but could also lead to VERY weird bugs, so we + // make sure the files don't exist. + if (lowerCase.exists()) lowerCase.delete() + if (upperCase.exists()) upperCase.delete() + + lowerCase.createNewFile() + + val insensitive = upperCase.exists() + lowerCase.delete() + + isCaseInsensitive = insensitive } + catch (e: IOException) { + println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.") + isCaseInsensitive = true + } + } // Worst-case: we're on Windows or using a FAT32 partition mounted in *nix. // Note: we allow / as the path separator and expect all \s to be converted @@ -79,11 +87,11 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { fun isValidFilename(name: String) = !name.contains(invalidChars) - fun validatePath(path: String) : String { - if (!isValidFilename(path)) { + fun String.validatePath() : String { + if (!isValidFilename(this)) { throw IOException("path contains invalid characters") } - return path + return this } /** actual directory: /Saves//computers// @@ -103,7 +111,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { */ // remove first '/' in path - var path = luapath.checkIBM437() + var path = luapath.checkIBM437().validatePath() if (path.startsWith('/')) path = path.substring(1) if (path.startsWith("media/")) { @@ -131,7 +139,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { Filesystem.ensurePathSanity(path) val table = LuaTable() - val file = File(computer.getRealPath(path)) + val file = File(computer.getRealPath(path)).absoluteFile file.list().forEachIndexed { i, s -> table.insert(i, LuaValue.valueOf(s)) } return table } @@ -141,7 +149,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(File(computer.getRealPath(path)).exists()) + return LuaValue.valueOf(Files.exists(Paths.get(computer.getRealPath(path)).toAbsolutePath())) } } @@ -149,7 +157,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(File(computer.getRealPath(path)).isDirectory) + return LuaValue.valueOf(Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath())) } } @@ -157,7 +165,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(File(computer.getRealPath(path)).isFile) + return LuaValue.valueOf(!Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath())) } } @@ -165,7 +173,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(!File(computer.getRealPath(path)).canWrite()) + return LuaValue.valueOf(!Files.isWritable(Paths.get(computer.getRealPath(path)).toAbsolutePath())) } } @@ -174,7 +182,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(File(computer.getRealPath(path)).length().toInt()) + return LuaValue.valueOf(Files.size(Paths.get(computer.getRealPath(path)).toAbsolutePath()).toInt()) } } @@ -187,7 +195,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { override fun call(path: LuaValue) : LuaValue { Filesystem.ensurePathSanity(path) - return LuaValue.valueOf(File(computer.getRealPath(path)).mkdir()) + return LuaValue.valueOf(File(computer.getRealPath(path)).absoluteFile.mkdir()) } } @@ -199,11 +207,12 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { Filesystem.ensurePathSanity(from) Filesystem.ensurePathSanity(to) - val fromFile = File(computer.getRealPath(from)) + val fromFile = File(computer.getRealPath(from)).absoluteFile var success = fromFile.copyRecursively( - File(computer.getRealPath(to)), overwrite = true - ) // ignore IntelliJ's observation; it's opposite from redundant - success = fromFile.deleteRecursively() + File(computer.getRealPath(to)).absoluteFile, overwrite = true + ) + if (success) success = fromFile.deleteRecursively() + else return LuaValue.valueOf(false) return LuaValue.valueOf(success) } } @@ -218,8 +227,8 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { Filesystem.ensurePathSanity(to) return LuaValue.valueOf( - File(computer.getRealPath(from)).copyRecursively( - File(computer.getRealPath(to)), overwrite = true + File(computer.getRealPath(from)).absoluteFile.copyRecursively( + File(computer.getRealPath(to)).absoluteFile, overwrite = true ) ) } @@ -233,7 +242,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { Filesystem.ensurePathSanity(path) return LuaValue.valueOf( - File(computer.getRealPath(path)).deleteRecursively() + File(computer.getRealPath(path)).absoluteFile.deleteRecursively() ) } } @@ -243,7 +252,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { Filesystem.ensurePathSanity(base) Filesystem.ensurePathSanity(local) - val combinedPath = combinePath(base.checkIBM437(), local.checkIBM437()) + val combinedPath = combinePath(base.checkIBM437().validatePath(), local.checkIBM437().validatePath()) return LuaValue.valueOf(combinedPath) } } @@ -282,9 +291,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { val mode = mode.checkIBM437().toLowerCase() val luaClass = LuaTable() - val file = File(computer.getRealPath(path)) + val file = File(computer.getRealPath(path)).absoluteFile - if (mode.contains("[aw]") && !file.canWrite()) + if (mode.contains(Regex("""[aw]""")) && !file.canWrite()) throw LuaError("Cannot open file for " + "${if (mode.startsWith('w')) "read" else "append"} mode" + ": is readonly.") diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/Input.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/Input.kt index f56c0c7bc..015d71f5d 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/Input.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/Input.kt @@ -15,6 +15,7 @@ class Input(globals: Globals, computer: BaseTerrarumComputer) { init { globals["input"] = LuaTable() globals["input"]["isKeyDown"] = IsKeyDown(computer) + // input.readLine defined in ROMLIB } companion object { diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/Term.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/Term.kt index 05fbaabb2..90d986564 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/Term.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/Term.kt @@ -118,6 +118,7 @@ internal class Term(globals: Globals, term: Teletype) { } } + // emitchar class Emit(val term: Terminal) : ThreeArgFunction() { override fun call(p0: LuaValue, x: LuaValue, y: LuaValue): LuaValue { term.emitChar(p0.checkint().toChar(), x.checkint() - 1, y.checkint() - 1)