Skip to content

Commit

Permalink
Prevent Crash on Text Change (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
alonalbert authored May 3, 2024
1 parent 8cba196 commit dbc81f7
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 19 deletions.
16 changes: 2 additions & 14 deletions src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package dev.romainguy.kotlin.explorer

import dev.romainguy.kotlin.explorer.jump.JumpDetector
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
import java.awt.Graphics
import java.awt.Graphics2D
Expand All @@ -24,11 +25,9 @@ import javax.swing.event.CaretListener

open class CodeTextArea(
private val explorerState: ExplorerState,
jumpRegex: Regex,
addressedRegex: Regex,
private val jumpDetector: JumpDetector,
private val lineNumberRegex: Regex?,
) : RSyntaxTextArea() {
private val jumpDetector = JumpDetector(jumpRegex, addressedRegex)
private var jumpOffsets: JumpOffsets? = null
private var fullText = ""

Expand Down Expand Up @@ -114,17 +113,6 @@ open class CodeTextArea(
} ?: this

private data class JumpOffsets(val src: Int, val dst: Int)

private class Jump(val address: String, val direction: Int)

private class JumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) {
fun detectJump(line: String): Jump? {
val match = jumpRegex.matchEntire(line) ?: return null
return Jump(match.getValue("address"), if (match.getValue("direction") == "+") 1 else -1)
}

fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address")
}
}

private fun String.countPadding() = indexOfFirst { it != ' ' }
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package dev.romainguy.kotlin.explorer.dex

import dev.romainguy.kotlin.explorer.CodeTextArea
import dev.romainguy.kotlin.explorer.ExplorerState
import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector

// DEX Syntax: ' 0005: if-nez v0, 0008 // +0003'
private val DexJumpRegex =
Regex("^.{9}[0-9a-fA-F]{4}: .+(?<address>[0-9a-fA-F]{4}) // (?<direction>[+-])[0-9a-fA-F]{4}$")
private val DexAddressedRegex = Regex("^.{9}(?<address>[0-9a-fA-F]{4}): .+$")
private val DexLineNumberRegex = Regex("^(?<lineNumber> +\\d+: )([0-9a-f]{4}: )", RegexOption.MULTILINE)

class DexTextArea(explorerState: ExplorerState) :
CodeTextArea(explorerState, DexJumpRegex, DexAddressedRegex, DexLineNumberRegex)
CodeTextArea(explorerState, RegexJumpDetector(DexJumpRegex, DexAddressedRegex), DexLineNumberRegex)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2023 Romain Guy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.romainguy.kotlin.explorer.jump

class CompoundJumpDetector(private vararg val detectors: JumpDetector) : JumpDetector {
override fun detectJump(line: String) = detectors.firstNotNullOfOrNull { it.detectJump(line) }

override fun detectAddressed(line: String) = detectors.firstNotNullOfOrNull { it.detectAddressed(line) }
}
19 changes: 19 additions & 0 deletions src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2023 Romain Guy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.romainguy.kotlin.explorer.jump

class Jump(val address: Int, val direction: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2023 Romain Guy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.romainguy.kotlin.explorer.jump

interface JumpDetector {
fun detectJump(line: String): Jump?

fun detectAddressed(line: String): Int?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 Romain Guy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.romainguy.kotlin.explorer.jump

import dev.romainguy.kotlin.explorer.getValue

class RegexJumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) : JumpDetector {
override fun detectJump(line: String): Jump? {
val match = jumpRegex.matchEntire(line) ?: return null
return Jump(match.getValue("address").toInt(16), if (match.getValue("direction") == "+") 1 else -1)
}

override fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address")?.toInt(16)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,29 @@ package dev.romainguy.kotlin.explorer.oat

import dev.romainguy.kotlin.explorer.CodeTextArea
import dev.romainguy.kotlin.explorer.ExplorerState
import dev.romainguy.kotlin.explorer.jump.CompoundJumpDetector
import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector

private val OatJumpRegex =
Regex("^ +0x[0-9a-fA-F]{8}: .+ (?<direction>[+-])\\d+ \\((?<address>0x[0-9a-fA-F]{8})\\)$")
private val OatAddressedRegex = Regex("^ +(?<address>0x[0-9a-fA-F]{8}): .+$")
// Arm64 syntax: ' 0x00001040: b.ge #+0x48 (addr 0x1088)'
private val Arm64JumpRegex =
Regex("^ +0x[0-9a-fA-F]{8}: .+ #(?<direction>[+-])0x[0-9a-fA-F]+ \\(addr 0x(?<address>[0-9a-fA-F]+)\\)$")

// X86 syntax: ' 0x00001048: jnl/ge +103 (0x000010b5)'
private val X86JumpRegex =
Regex("^ +0x[0-9a-fA-F]{8}: .+ (?<direction>[+-])\\d+ \\(0x(?<address>[0-9a-fA-F]{8})\\)$")

private val OatAddressedRegex = Regex("^ +0x(?<address>[0-9a-fA-F]{8}): .+$")

class OatTextArea(explorerState: ExplorerState) :
CodeTextArea(explorerState, OatJumpRegex, OatAddressedRegex, lineNumberRegex = null)
CodeTextArea(
explorerState,
CompoundJumpDetector(
RegexJumpDetector(Arm64JumpRegex, OatAddressedRegex),
RegexJumpDetector(X86JumpRegex, OatAddressedRegex)
),
lineNumberRegex = null
)

fun main() {
println(X86JumpRegex.matchEntire(" 0x00001048: jnl/ge +103 (0x000010b5)"))
}

0 comments on commit dbc81f7

Please sign in to comment.