Skip to content

Commit

Permalink
support more types to hide from toString method
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed Jan 23, 2024
1 parent 3f94c38 commit 6a7fd3c
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 27 deletions.
7 changes: 5 additions & 2 deletions sample/src/main/kotlin/KSPTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import dev.datlag.sekret.Secret

@Obfuscate
data class KSPTest<T>(
val data: String,
@Secret val data: java.lang.String,
@Secret val secret: String,
val testing: Int = 1337,
val subClass: Sub = Sub("sub-data"),
@Secret val charSeq: CharSequence = "abcdefg"
@Secret val charSeq: CharSequence = "abcdefg",
@Secret val javaCharSeq: java.lang.CharSequence = secret as java.lang.CharSequence,
@Secret val builder: StringBuilder = StringBuilder("string-builder"),
@Secret val appendable: Appendable = builder
) {
val other: String = "test"
}
Expand Down
2 changes: 1 addition & 1 deletion sample/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fun main() {
val secretValue = Sekret.testKey("password12345")
println("Decoded secret: $secretValue")
}
val testing = KSPTest<Int>("my-data", "my-secret")
val testing = KSPTest<Int>(java.lang.String("java-string"), "my-secret")
println(testing.toString())
println(testing.secret)
println(testing.charSeq)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
package dev.datlag.sekret

import dev.datlag.sekret.common.hasMatchingAnnotation
import dev.datlag.sekret.common.matchesAnyProperty
import dev.datlag.sekret.common.matchesProperty
import dev.datlag.sekret.common.*
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.backend.wasm.ir2wasm.allFields
import org.jetbrains.kotlin.backend.wasm.utils.hasWasmAutoboxedAnnotation
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.builders.irString
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.isCharSequence
import org.jetbrains.kotlin.ir.types.isNullableString
import org.jetbrains.kotlin.ir.types.isString
import org.jetbrains.kotlin.ir.types.typeConstructorParameters
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation
import org.jetbrains.kotlin.resolve.source.getPsi

class ElementTransformer(
private val config: Config,
Expand All @@ -42,7 +24,7 @@ class ElementTransformer(

val secretProperties = declaration.properties.filter { it.hasMatchingAnnotation(secretAnnotation, declaration) }
if (secretProperties.count() > 0) {
declaration.getSimpleFunction("toString")?.owner?.transform(
declaration.getSimpleFunction("toString")?.owner?.transformChildren(
ToStringTransformer(secretProperties.toList(), config, logger, pluginContext),
null
)
Expand All @@ -59,10 +41,12 @@ class ToStringTransformer(
private val pluginContext: IrPluginContext
) : IrElementTransformerVoidWithContext() {
override fun visitGetField(expression: IrGetField): IrExpression {
val stringField = expression.type.isString() || (config.secretMaskNull && expression.type.isNullableString())
val charSequence = expression.type.isCharSequence()
val string = expression.type.isAnyString(config.secretMaskNull)
val charSequence = expression.type.isAnyCharSequence(config.secretMaskNull)
val stringBuilder = expression.type.isAnyStringBuilder(config.secretMaskNull)
val appendable = expression.type.isAnyAppendable(config.secretMaskNull)

if (stringField || charSequence) {
if (string || charSequence || stringBuilder || appendable) {
if (expression.symbol.owner.matchesAnyProperty(secretProperties)) {
return DeclarationIrBuilder(pluginContext, expression.symbol).irString(config.secretMask)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.datlag.sekret

import org.jetbrains.kotlin.ir.types.getPublicSignature

object JavaSignatureValues {
@JvmField val string = getPublicSignature(JavaStandardNames.LANG_PACKAGE_FQ_NAME, "String")
@JvmField val charSequence = getPublicSignature(JavaStandardNames.LANG_PACKAGE_FQ_NAME, "CharSequence")
@JvmField val stringBuilder = getPublicSignature(JavaStandardNames.LANG_PACKAGE_FQ_NAME, "StringBuilder")
@JvmField val appendable = getPublicSignature(JavaStandardNames.LANG_PACKAGE_FQ_NAME, "Appendable")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.datlag.sekret

import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name

object JavaStandardNames {

@JvmField
val BUILT_INS_PACKAGE_NAME = Name.identifier("java")

@JvmField
val BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME)

@JvmField
val LANG_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("lang"))
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package dev.datlag.sekret.common

import dev.datlag.sekret.JavaSignatureValues
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName

Expand Down Expand Up @@ -56,4 +59,43 @@ fun IrField.matchesProperty(property: IrProperty): Boolean {

fun IrField.matchesAnyProperty(properties: Iterable<IrProperty>): Boolean {
return properties.any { this.matchesProperty(it) }
}

fun IrType.matches(signature: IdSignature.CommonSignature, nullable: Boolean? = null): Boolean {
if (this !is IrSimpleType) return false
if (nullable != null && this.isMarkedNullable() != nullable) return false
return signature == classifier.signature ||
classifier.owner.let { it is IrClass && it.signatureMatchesFqName(signature) }
}

fun IrClass.signatureMatchesFqName(signature: IdSignature.CommonSignature): Boolean =
name.asString() == signature.shortName &&
hasEqualFqName(FqName("${signature.packageFqName}.${signature.declarationFqName}"))

fun IrType.matchesPossibleNull(signature: IdSignature.CommonSignature, nullable: Boolean = false): Boolean {
return matches(signature, false) || (nullable && matches(signature, true))
}

fun IrType.isAnyString(nullable: Boolean = false): Boolean {
return this.matchesPossibleNull(IdSignatureValues.string, nullable = nullable)
|| this.matchesPossibleNull(JavaSignatureValues.string, nullable = nullable)
}

fun IrType.isAnyCharSequence(nullable: Boolean = false): Boolean {
return this.matchesPossibleNull(IdSignatureValues.charSequence, nullable = nullable)
|| this.matchesPossibleNull(JavaSignatureValues.charSequence, nullable = nullable)
}

fun IrType.isAnyStringBuilder(nullable: Boolean = false): Boolean {
return this.matchesPossibleNull(
getPublicSignature(StandardNames.TEXT_PACKAGE_FQ_NAME, "StringBuilder"),
nullable = nullable
) || this.matchesPossibleNull(JavaSignatureValues.stringBuilder, nullable = nullable)
}

fun IrType.isAnyAppendable(nullable: Boolean = false): Boolean {
return this.matchesPossibleNull(
getPublicSignature(StandardNames.TEXT_PACKAGE_FQ_NAME, "Appendable"),
nullable = nullable
) || this.matchesPossibleNull(JavaSignatureValues.appendable, nullable = nullable)
}

0 comments on commit 6a7fd3c

Please sign in to comment.