diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index ddc69a789..8ef00ee37 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -925,6 +925,14 @@ opencomputers { # not apply to HTTP traffic. maxNetworkPacketSize: 8192 + # The maximum number of "data parts" a network packet is allowed to have. + # When sending a network message, from Lua this may look like so: + # component.modem.broadcast(port, "first", true, "third", 123) + # This limits how many arguments can be passed and are wrapped into a + # packet. This limit mostly serves as a protection for lower-tier + # computers, to avoid them getting nuked by more powerful computers. + maxNetworkPacketParts: 8 + # The maximum number of ports a single network card can have opened at # any given time. maxOpenPorts: 16 diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index 8d3a806ec..619d30c59 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -271,6 +271,7 @@ class Settings(val config: Config) { val inputUsername = config.getBoolean("misc.inputUsername") val maxClipboard = config.getInt("misc.maxClipboard") max 0 val maxNetworkPacketSize = config.getInt("misc.maxNetworkPacketSize") max 0 + val maxNetworkPacketParts = config.getInt("misc.maxNetworkPacketParts") max 0 val maxOpenPorts = config.getInt("misc.maxOpenPorts") max 0 val maxWirelessRange = config.getDouble("misc.maxWirelessRange") max 0 val rTreeMaxEntries = 10 diff --git a/src/main/scala/li/cil/oc/server/network/Network.scala b/src/main/scala/li/cil/oc/server/network/Network.scala index 3625d4fda..dc559092e 100644 --- a/src/main/scala/li/cil/oc/server/network/Network.scala +++ b/src/main/scala/li/cil/oc/server/network/Network.scala @@ -662,17 +662,22 @@ object Network extends api.detail.NetworkAPI { // ----------------------------------------------------------------------- // class Packet(var source: String, var destination: String, var port: Int, var data: Array[AnyRef], var ttl: Int = 5) extends api.network.Packet { - val size = Option(data).fold(0)(_.foldLeft(0)((acc, arg) => { - acc + (arg match { - case null | Unit | None => 4 - case _: java.lang.Boolean => 4 - case _: java.lang.Integer => 4 - case _: java.lang.Double => 8 - case value: java.lang.String => value.length max 1 - case value: Array[Byte] => value.length max 1 - case _ => throw new IllegalArgumentException("unsupported data type") + val size = Option(data).fold(0)(values => { + if (values.length > Settings.get.maxNetworkPacketParts) { + throw new IllegalArgumentException("packet has too many parts") + } + values.length * 2 + values.foldLeft(0)((acc, arg) => { + acc + (arg match { + case null | Unit | None => 4 + case _: java.lang.Boolean => 4 + case _: java.lang.Integer => 4 + case _: java.lang.Double => 8 + case value: java.lang.String => value.length max 1 + case value: Array[Byte] => value.length max 1 + case _ => throw new IllegalArgumentException("unsupported data type") + }) }) - })) + }) override def hop() = new Packet(source, destination, port, data, ttl - 1)