Mercurial > cgi-bin > hgweb.cgi > PassMan
changeset 3:eafa3779aef8
More bug fixes, quote strings in diagnostics.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 11 Sep 2022 20:36:06 -0700 |
parents | 3c792ad36b3d |
children | 02b101422726 |
files | pom.xml src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt src/main/kotlin/name/blackcap/passman/Database.kt src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt src/main/kotlin/name/blackcap/passman/Main.kt src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt src/main/kotlin/name/blackcap/passman/See.kt src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt |
diffstat | 8 files changed, 67 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/pom.xml Sun Sep 11 18:24:55 2022 -0700 +++ b/pom.xml Sun Sep 11 20:36:06 2022 -0700 @@ -81,24 +81,23 @@ <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> + <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> - <configuration> - <archive> - <manifest> - <mainClass> - name.blackcap.passman.MainKt - </mainClass> - </manifest> - </archive> - <descriptorRefs> - <descriptorRef>jar-with-dependencies</descriptorRef> - </descriptorRefs> - </configuration> </execution> </executions> + <configuration> + <archive> + <manifest> + <mainClass>name.blackcap.passman.MainKt</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> </plugin> </plugins> </build>
--- a/src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt Sun Sep 11 20:36:06 2022 -0700 @@ -29,7 +29,7 @@ val length = try { rawLength?.toInt() ?: DEFAULT_GENERATED_LENGTH } catch (e: NumberFormatException) { - die("$rawLength - invalid length") + die("${see(rawLength)} - invalid length") -1 /* will never happen */ } val symbols = commandLine.hasOption("symbols") @@ -46,7 +46,7 @@ result.next() val count = result.getInt(1) if (count > 0) { - die("record matching ${entry.name} already exists") + die("record matching ${see(entry.name)} already exists") } }
--- a/src/main/kotlin/name/blackcap/passman/Database.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/Database.kt Sun Sep 11 20:36:06 2022 -0700 @@ -18,9 +18,9 @@ val exists = Files.exists(Path.of(fileName)) if (!exists) { if (create) { - error("initializing database $fileName") + error("initializing database ${see(fileName, simple = true)}") } else { - die("$fileName not found") + die("${see(fileName, simple = true)} not found") } } val masterPassword = getPassword(passwordPrompt, !exists) @@ -99,8 +99,6 @@ val readFromDb = result.getDecryptedString(1, database.encryption) if (readFromDb != PLAINTEXT) { /* might also get thrown by getDecryptedString if bad */ - println(" got: " + dump(readFromDb)) - println("expected: " + dump(PLAINTEXT)) throw GeneralSecurityException("bad key!") } }
--- a/src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt Sun Sep 11 20:36:06 2022 -0700 @@ -2,6 +2,19 @@ class DeleteSubcommand(): Subcommand() { override fun run(args: Array<String>) { - println("Not yet implemented") + if (args.isEmpty()) { + die("expecting a site name", 2) + } + if (args.size > 1) { + die("unexpected trailing arguments", 2) + } + val nameIn = args[0] + val db = Database.open() + db.connection.prepareStatement("delete from passwords where id = ?").use { + it.setLong(1, db.makeKey(nameIn)) + if (it.executeUpdate() == 0) { + die("no record matches ${see(nameIn)}") + } + } } } \ No newline at end of file
--- a/src/main/kotlin/name/blackcap/passman/Main.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/Main.kt Sun Sep 11 20:36:06 2022 -0700 @@ -21,7 +21,7 @@ fun runSubcommand(name: String, args: Array<String>): Unit { val instance = getInstanceForClass(getClassForSubcommand(name)) if (instance == null) { - die("$name - unknown subcommand", 2) + die("${see(name)} - unknown subcommand", 2) } else { instance.run(args) }
--- a/src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt Sun Sep 11 20:36:06 2022 -0700 @@ -31,7 +31,7 @@ it.setLong(1, id) val result = it.executeQuery() if (!result.next()) { - die("no record matches $nameIn") + die("no record matches ${see(nameIn)}") } val entry = Entry( name = result.getDecryptedString(1, db.encryption), @@ -63,4 +63,4 @@ it.execute() } } -} \ No newline at end of file +}
--- a/src/main/kotlin/name/blackcap/passman/See.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/See.kt Sun Sep 11 20:36:06 2022 -0700 @@ -1,56 +1,46 @@ package name.blackcap.passman +/* Would be nice if there was a more programmatic and comprehensive way of + doing this, but alas. Even the oft-recommended StringEscapeUtils does + something cruder than the below. Le sigh. */ + import java.util.Formatter -private val UNPRINTABLE = setOf<Character.UnicodeBlock>( - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_EXTENDED, - Character.UnicodeBlock.COMBINING_HALF_MARKS, - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_SUPPLEMENT, - Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, - Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, - Character.UnicodeBlock.HIGH_SURROGATES, - Character.UnicodeBlock.LOW_SURROGATES, - Character.UnicodeBlock.PRIVATE_USE_AREA, - Character.UnicodeBlock.SPECIALS, +private const val DELIM = '"' -) +private val STD_ESC_MAP = mapOf<Char, Char>('\t' to 't', '\b' to 'b', '\n' to 'n', + '\r' to 'r', '\u000c' to 'f', '\"' to '"', '\\' to '\\') +private const val MIN_ASCII = ' ' +private const val MAX_ASCII = '~' +private const val MIN_8859 = '\u00a1' +private const val MAX_8859 = '\u00ff' +private const val SHY = '\u00ad' -private val DELIM = '"' +fun see(input: String, simple: Boolean = false): String = + if (simple) seeSimple(input) else seeAggressive(input) -private val EXEMPT = setOf<Char>(' ') -private val PREFIXED = setOf<Char>(DELIM, '\\') +private fun seeSimple(input: String): String = StringBuilder().run { + append(DELIM) + append(input) + append(DELIM) + toString() +} -fun see(input: String): String { - val accum = StringBuilder() - val formatter = Formatter(accum) - accum.append(DELIM) +private fun seeAggressive(input: String): String { + val accum = Formatter() + accum.format("%c", DELIM) for (ch in input) { - val block = Character.UnicodeBlock.of(ch) - if (ch in EXEMPT) { - accum.append(ch) - } else if (block == null || block in UNPRINTABLE || Character.isSpaceChar(ch) || Character.isWhitespace(ch)) { - formatter.format("\\u%04x", ch.code) - } else if (ch in PREFIXED) { - accum.append('\\') - accum.append(ch) + if ((ch in MIN_ASCII..MAX_ASCII) || ((ch != SHY) && (ch in MIN_8859 .. MAX_8859))) { + accum.format("%c", ch) + continue + } + val mapped = STD_ESC_MAP[ch] + if (mapped != null) { + accum.format("\\%c", mapped) } else { - accum.append(ch) + accum.format("\\u%04x", ch.code) } } - accum.append(DELIM) + accum.format("%c", DELIM) return accum.toString() } - -fun dump(input: String): String { - val accum = StringBuilder() - var needSpace = false - for (ch in input) { - if (needSpace) { - accum.append(' ') - } - accum.append(ch.code) - needSpace = true - } - return accum.toString() -}
--- a/src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt Sun Sep 11 20:36:06 2022 -0700 @@ -53,7 +53,7 @@ try { rawLength?.toInt() ?: DEFAULT_GENERATED_LENGTH } catch (e: NumberFormatException) { - die("$rawLength - invalid length") + die("${see(rawLength)} - invalid length") -1 /* will never happen */ } } @@ -90,7 +90,7 @@ result.next() val count = result.getInt(1) if (count < 1) { - die("no record matches $nameIn") + die("no record matches " + see(nameIn)) } } } @@ -167,4 +167,4 @@ addOne("password", newPassword) } -} \ No newline at end of file +}