Better handle large numbers from external data files (#3791)

Co-authored-by: Martin Haug <mhaug@live.de>
This commit is contained in:
Ana Gelez 2024-03-25 17:51:35 +01:00 committed by Laurenz
parent c5dcd220c1
commit cdd8d167cf
7 changed files with 35 additions and 9 deletions

2
Cargo.lock generated
View File

@ -2630,7 +2630,7 @@ dependencies = [
[[package]]
name = "typst-dev-assets"
version = "0.11.0"
source = "git+https://github.com/typst/typst-dev-assets?tag=v0.11.0#e0ef7ad46f28a440c41bc8e78563ace86cc02678"
source = "git+https://github.com/typst/typst-dev-assets?rev=ee8ae61cca138dc92f9d818fc7f2fc046d0148c5#ee8ae61cca138dc92f9d818fc7f2fc046d0148c5"
[[package]]
name = "typst-docs"

View File

@ -26,7 +26,7 @@ typst-svg = { path = "crates/typst-svg", version = "0.11.0" }
typst-syntax = { path = "crates/typst-syntax", version = "0.11.0" }
typst-timing = { path = "crates/typst-timing", version = "0.11.0" }
typst-assets = "0.11.0"
typst-dev-assets = { git = "https://github.com/typst/typst-dev-assets", tag = "v0.11.0" }
typst-dev-assets = { git = "https://github.com/typst/typst-dev-assets", rev = "ee8ae61cca138dc92f9d818fc7f2fc046d0148c5" }
az = "1.2"
base64 = "0.22"
bitflags = { version = "2", features = ["serde"] }

View File

@ -261,7 +261,14 @@ macro_rules! unsigned_int {
($($ty:ty)*) => {
$(cast! {
$ty,
self => Value::Int(self as _),
self => if let Ok(int) = i64::try_from(self) {
Value::Int(int)
} else {
// Some u64 are too large to be cast as i64
// In that case, we accept that there may be a
// precision loss, and use a floating point number
Value::Float(self as _)
},
v: i64 => v.try_into().map_err(|_| {
if v < 0 {
"number must be at least zero"

View File

@ -14,6 +14,9 @@ use crate::World;
/// equivalents, null-values (`null`, `~` or empty ``) will be converted into
/// `{none}`, and numbers will be converted to floats or integers depending on
/// whether they are whole numbers.
///
/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
/// floating point numbers, which may result in an approximative value.
#[func(scope, title = "CBOR")]
pub fn cbor(
/// The engine.

View File

@ -9,13 +9,18 @@ use crate::World;
/// Reads structured data from a JSON file.
///
/// The file must contain a valid JSON object or array. JSON objects will be
/// converted into Typst dictionaries, and JSON arrays will be converted into
/// Typst arrays. Strings and booleans will be converted into the Typst
/// equivalents, `null` will be converted into `{none}`, and numbers will be
/// converted to floats or integers depending on whether they are whole numbers.
/// The file must contain a valid JSON value, such as object or array. JSON
/// objects will be converted into Typst dictionaries, and JSON arrays will be
/// converted into Typst arrays. Strings and booleans will be converted into the
/// Typst equivalents, `null` will be converted into `{none}`, and numbers will
/// be converted to floats or integers depending on whether they are whole
/// numbers.
///
/// The function returns a dictionary or an array, depending on the JSON file.
/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
/// floating point numbers, which may result in an approximative value.
///
/// The function returns a dictionary, an array or, depending on the JSON file,
/// another JSON data type.
///
/// The JSON files in the example contain objects with the keys `temperature`,
/// `unit`, and `weather`.

View File

@ -17,6 +17,9 @@ use crate::World;
/// whether they are whole numbers. Custom YAML tags are ignored, though the
/// loaded value will still be present.
///
/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
/// floating point numbers, which may give an approximative value.
///
/// The YAML files in the example contain objects with authors as keys,
/// each with a sequence of their own submapping with the keys
/// "title" and "published"

View File

@ -0,0 +1,8 @@
// Big numbers (larger than what i64 can store) should just lose some precision
// but not overflow
// https://github.com/typst/typst/issues/3363
// Ref: false
#let bignum = json("/assets/data/big-number.json")
#bignum