diff options
author | Edoardo La Greca | 2025-07-30 18:57:19 +0200 |
---|---|---|
committer | Edoardo La Greca | 2025-07-30 18:57:19 +0200 |
commit | 4050df8178def9df2107bab3d49ae97282f79e53 (patch) | |
tree | 406066772a88a6e32c959aa6992ccd8b2f38fcf2 | |
parent | ef004bfc3d766fdc00216093f1796ec1c74f7dd7 (diff) |
enforce msize observance
-rw-r--r-- | src/main/kotlin/NinePConnection.kt | 13 | ||||
-rw-r--r-- | src/main/kotlin/NinePMessage.kt | 8 |
2 files changed, 15 insertions, 6 deletions
diff --git a/src/main/kotlin/NinePConnection.kt b/src/main/kotlin/NinePConnection.kt index 6f678a0..5adb35b 100644 --- a/src/main/kotlin/NinePConnection.kt +++ b/src/main/kotlin/NinePConnection.kt @@ -127,10 +127,14 @@ class NinePConnection(netPackTrans: NetworkPacketTransporter) : NinePTranslator } /** - * Send 9P request and check for Rerror response. + * Send 9P request and check for exceptions or a Rerror response. */ private fun responseError(msg: NinePMessage): String? { - msg.write(this.npt) + try { + msg.write(this.npt) + } catch (ex: Exception) { + return "Exception thrown while sending message: (" + ex.javaClass.toString() + ") " + ex.message + } val se = waitForTag(msg.tag) if (se.second == NinePMessageType.RERROR) { val error = readError() @@ -146,7 +150,8 @@ class NinePConnection(netPackTrans: NetworkPacketTransporter) : NinePTranslator ), mapOf( "version" to version - ) + ), + this.maxSize ) val error = responseError(msg) if (error != null) { @@ -157,7 +162,7 @@ class NinePConnection(netPackTrans: NetworkPacketTransporter) : NinePTranslator // this check should not be necessary, but you never know this.maxSize = ( if (rmsize < msize.value) msize.value else rmsize ).toInt().toUInt() if (rversion == "unknown") { - return "Unknown version" + return "Unknown version." } return null } diff --git a/src/main/kotlin/NinePMessage.kt b/src/main/kotlin/NinePMessage.kt index 1d0530a..87d59a5 100644 --- a/src/main/kotlin/NinePMessage.kt +++ b/src/main/kotlin/NinePMessage.kt @@ -13,7 +13,7 @@ import kotlin.math.pow * @param fieldValuesInt A map of each field name into its value. This map only stores integer values. * @param fieldValuesStr A map of each field name into its value. This map only stores string values. */ -class NinePMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: List<String>, val fieldValuesInt: Map<String, SizedMessageField>, val fieldValuesStr: Map<String, String>) { +class NinePMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: List<String>, val fieldValuesInt: Map<String, SizedMessageField>, val fieldValuesStr: Map<String, String>, val maxSize: UInt) { /** * Intersection between [fieldNames] and [fieldValuesInt]. In other words: the amount of integer fields that are * going to be used when writing the message. @@ -29,13 +29,17 @@ class NinePMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: * Send the message using the given networking API. * * @param npt The networking API. - * @throws IllegalArgumentException if [fieldNames], [fieldValuesInt], and [fieldValuesStr] are incoherent. + * @throws IllegalArgumentException if [fieldNames], [fieldValuesInt], and [fieldValuesStr] are incoherent or the + * final size of the message exceeds the negotiated value. */ fun write(npt: NetworkPacketTransporter) { // check that names in fieldNames exist as keys in either fieldValuesInt or fieldValuesStr but not both require(insecInts.size == fieldNames.size - insecStrs.size) val totalSize = size() + if (totalSize > this.maxSize.toLong()) { + throw IllegalArgumentException("Message size exceeded.") + } writeMessageSizeType(npt, totalSize, type) writeInteger(npt, SizedMessageField(2, tag.toInt().toBigInteger())) for (field in fieldNames) { |