somewhat mimic Lua 5.3+ conversion logic for numbers in API arguments, fix #3620

This commit is contained in:
Adrian Siekierka 2023-06-03 15:37:22 +02:00
parent c71c1479dd
commit 66bd036ed9
2 changed files with 57 additions and 18 deletions

View File

@ -1,13 +1,9 @@
## Fixes/improvements
* Reverted Internet Card code to OC 1.7.7, fixing the many related regressions.
* Fixed "number expected, got number" being displayed instead of "number has no integer representation" on Lua 5.3+.
* Fixed math.randomseed() not working with non-integer values.
* [#3620] Fixed OC 1.8.0+ regression involving API arguments and numbers.
## OpenOS fixes/improvements
* Fixed OpenOS version number.
## List of contributors
asie

View File

@ -58,10 +58,28 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
}
def checkInteger(index: Int) = {
checkIndex(index, "number")
checkIndex(index, "integer")
args(index) match {
case value: java.lang.Double =>
if (!java.lang.Double.isFinite(value) || value < java.lang.Integer.MIN_VALUE || value > java.lang.Integer.MAX_VALUE) {
throw intError(index, value)
} else {
value.intValue
}
case value: java.lang.Float =>
if (!java.lang.Float.isFinite(value) || value < java.lang.Integer.MIN_VALUE || value > java.lang.Integer.MAX_VALUE) {
throw intError(index, value)
} else {
value.intValue
}
case value: java.lang.Long =>
if (value < java.lang.Integer.MIN_VALUE || value > java.lang.Integer.MAX_VALUE) {
throw intError(index, value)
} else {
value.intValue
}
case value: java.lang.Number => value.intValue
case value => throw typeError(index, value, "number")
case value => throw typeError(index, value, "integer")
}
}
@ -71,10 +89,22 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
}
def checkLong(index: Int) = {
checkIndex(index, "number")
checkIndex(index, "integer")
args(index) match {
case value: java.lang.Double =>
if (!java.lang.Double.isFinite(value) || value < java.lang.Long.MIN_VALUE || value > java.lang.Long.MAX_VALUE) {
throw intError(index, value)
} else {
value.longValue
}
case value: java.lang.Float =>
if (!java.lang.Float.isFinite(value) || value < java.lang.Long.MIN_VALUE || value > java.lang.Long.MAX_VALUE) {
throw intError(index, value)
} else {
value.longValue
}
case value: java.lang.Number => value.longValue
case value => throw typeError(index, value, "number")
case value => throw typeError(index, value, "integer")
}
}
@ -157,22 +187,31 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
def isDouble(index: Int) =
index >= 0 && index < count && (args(index) match {
case value: java.lang.Float => true
case value: java.lang.Double => true
case value: java.lang.Number => true
case _ => false
})
def isInteger(index: Int) =
index >= 0 && index < count && (args(index) match {
case value: java.lang.Byte => true
case value: java.lang.Short => true
case value: java.lang.Integer => true
case value: java.lang.Long => true
case value: java.lang.Double => true
case value: java.lang.Double =>
java.lang.Double.isFinite(value) && value >= java.lang.Integer.MIN_VALUE && value <= java.lang.Integer.MAX_VALUE
case value: java.lang.Float =>
java.lang.Float.isFinite(value) && value >= java.lang.Integer.MIN_VALUE && value <= java.lang.Integer.MAX_VALUE
case value: java.lang.Long =>
value >= java.lang.Integer.MIN_VALUE && value <= java.lang.Integer.MAX_VALUE
case value: java.lang.Number => true
case _ => false
})
def isLong(index: Int) = isInteger(index)
def isLong(index: Int) =
index >= 0 && index < count && (args(index) match {
case value: java.lang.Double =>
java.lang.Double.isFinite(value) && value >= java.lang.Long.MIN_VALUE && value <= java.lang.Long.MAX_VALUE
case value: java.lang.Float =>
java.lang.Float.isFinite(value) && value >= java.lang.Long.MIN_VALUE && value <= java.lang.Long.MAX_VALUE
case value: java.lang.Number => true
case _ => false
})
def isString(index: Int) =
index >= 0 && index < count && (args(index) match {
@ -222,6 +261,10 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
new IllegalArgumentException(
s"bad argument #${index + 1} ($want expected, got ${typeName(have)})")
private def intError(index: Int, have: AnyRef) =
new IllegalArgumentException(
s"bad argument #${index + 1} (${typeName(have)} has no integer representation)")
private def typeName(value: AnyRef): String = value match {
case null | Unit | None => "nil"
case _: java.lang.Boolean => "boolean"
@ -229,7 +272,7 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments {
case _: java.lang.Short => "integer"
case _: java.lang.Integer => "integer"
case _: java.lang.Long => "integer"
case _: java.lang.Number => "double"
case _: java.lang.Number => "number"
case _: java.lang.String => "string"
case _: Array[Byte] => "string"
case value: java.util.Map[_, _] => "table"