Upgrade unsafe-libyaml to 0.2.10

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/unsafe-libyaml
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: Ie070d25787fda1157b54422773263f4a7228853e
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 09e6054..3b85faf 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "9651508612c804480141a6f57839e7af729559f7"
+    "sha1": "61f3ab82b271ac90d6a04f65520614ca08c58abe"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8661567..c3beee9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,10 +24,10 @@
     strategy:
       fail-fast: false
       matrix:
-        rust: [nightly, beta, stable, 1.62.0]
+        rust: [nightly, beta, stable, 1.63.0]
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@master
         with:
           toolchain: ${{matrix.rust}}
@@ -43,17 +43,31 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@1.56.0
       - run: cargo check --lib
 
+  doc:
+    name: Documentation
+    needs: pre_ci
+    if: needs.pre_ci.outputs.continue
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    env:
+      RUSTDOCFLAGS: -Dwarnings
+    steps:
+      - uses: actions/checkout@v4
+      - uses: dtolnay/rust-toolchain@nightly
+      - uses: dtolnay/install@cargo-docs-rs
+      - run: cargo docs-rs
+
   clippy:
     name: Clippy
     runs-on: ubuntu-latest
     if: github.event_name != 'pull_request'
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@clippy
       - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
 
@@ -64,7 +78,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@miri
       - run: cargo miri setup
       - run: cargo miri test
@@ -78,7 +92,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@nightly
       - uses: dtolnay/install@cargo-fuzz
       - run: cargo fuzz check
@@ -89,7 +103,7 @@
     if: github.event_name != 'pull_request'
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/install@cargo-outdated
       - run: cargo outdated --workspace --exit-code 1
       - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
diff --git a/Android.bp b/Android.bp
index 0545cf9..ad903b6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5,7 +5,7 @@
     name: "libunsafe_libyaml",
     crate_name: "unsafe_libyaml",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.9",
+    cargo_pkg_version: "0.2.10",
     srcs: ["src/lib.rs"],
     edition: "2021",
 }
@@ -14,7 +14,7 @@
     name: "run_emitter_test_suite",
     crate_name: "run_emitter_test_suite",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.9",
+    cargo_pkg_version: "0.2.10",
     srcs: ["src/bin/run-emitter-test-suite.rs"],
     edition: "2021",
     rustlibs: ["libunsafe_libyaml"],
@@ -24,7 +24,7 @@
     name: "run_parser_test_suite",
     crate_name: "run_parser_test_suite",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.9",
+    cargo_pkg_version: "0.2.10",
     srcs: ["src/bin/run-parser-test-suite.rs"],
     edition: "2021",
     rustlibs: ["libunsafe_libyaml"],
diff --git a/Cargo.toml b/Cargo.toml
index 31efefc..81e8a39 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.56"
 name = "unsafe-libyaml"
-version = "0.2.9"
+version = "0.2.10"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 description = "libyaml transpiled to rust by c2rust"
 documentation = "https://docs.rs/unsafe-libyaml"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index e6186b8..5ec7f85 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "unsafe-libyaml"
-version = "0.2.9" # remember to update html_root_url
+version = "0.2.10"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 categories = ["encoding", "parser-implementations", "no-std"]
 description = "libyaml transpiled to rust by c2rust"
diff --git a/METADATA b/METADATA
index ba4f960..3bb4995 100644
--- a/METADATA
+++ b/METADATA
@@ -1,19 +1,24 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update external/rust/crates/unsafe-libyaml
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
 name: "unsafe-libyaml"
 description: "libyaml transpiled to rust by c2rust"
 third_party {
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2024
+    month: 2
+    day: 7
+  }
   identifier {
     type: "crates.io"
-    value: "https://crates.io/crates/unsafe-libyaml"
+    value: "https://static.crates.io/crates/unsafe-libyaml/unsafe-libyaml-0.2.10.crate"
+    version: "0.2.10"
   }
   identifier {
     type: "Archive"
     value: "https://static.crates.io/crates/unsafe-libyaml/unsafe-libyaml-0.2.9.crate"
-  }
-  version: "0.2.9"
-  license_type: NOTICE
-  last_upgrade_date {
-    year: 2023
-    month: 8
-    day: 23
+    version: "0.2.10"
   }
 }
diff --git a/src/api.rs b/src/api.rs
index 2e44d66..c8bbcba 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -1,4 +1,5 @@
 use crate::externs::{free, malloc, memcpy, memmove, memset, realloc, strdup, strlen};
+use crate::ops::{ForceAdd as _, ForceMul as _};
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{size_t, yaml_char_t};
 use crate::{
@@ -53,17 +54,18 @@
 ) {
     let new_start: *mut yaml_char_t = yaml_realloc(
         *start as *mut libc::c_void,
-        ((*end).c_offset_from(*start) as libc::c_long * 2_i64) as size_t,
+        (((*end).c_offset_from(*start) as libc::c_long).force_mul(2_i64)) as size_t,
     ) as *mut yaml_char_t;
     memset(
         new_start.wrapping_offset((*end).c_offset_from(*start) as libc::c_long as isize)
             as *mut libc::c_void,
         0,
-        (*end).c_offset_from(*start) as libc::c_long as libc::c_ulong,
+        (*end).c_offset_from(*start) as libc::c_ulong,
     );
     *pointer = new_start.wrapping_offset((*pointer).c_offset_from(*start) as libc::c_long as isize);
-    *end =
-        new_start.wrapping_offset(((*end).c_offset_from(*start) as libc::c_long * 2_i64) as isize);
+    *end = new_start.wrapping_offset(
+        (((*end).c_offset_from(*start) as libc::c_long).force_mul(2_i64)) as isize,
+    );
     *start = new_start;
 }
 
@@ -86,7 +88,7 @@
     memcpy(
         *a_pointer as *mut libc::c_void,
         *b_start as *const libc::c_void,
-        (*b_pointer).c_offset_from(*b_start) as libc::c_long as libc::c_ulong,
+        (*b_pointer).c_offset_from(*b_start) as libc::c_ulong,
     );
     *a_pointer =
         (*a_pointer).wrapping_offset((*b_pointer).c_offset_from(*b_start) as libc::c_long as isize);
@@ -99,16 +101,16 @@
 ) {
     let new_start: *mut libc::c_void = yaml_realloc(
         *start,
-        ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
-            * 2_i64) as size_t,
+        (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long)
+            .force_mul(2_i64)) as size_t,
     );
     *top = (new_start as *mut libc::c_char).wrapping_offset(
         (*top as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
             as isize,
     ) as *mut libc::c_void;
     *end = (new_start as *mut libc::c_char).wrapping_offset(
-        ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
-            * 2_i64) as isize,
+        (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long)
+            .force_mul(2_i64)) as isize,
     ) as *mut libc::c_void;
     *start = new_start;
 }
@@ -122,8 +124,9 @@
     if *start == *head && *tail == *end {
         let new_start: *mut libc::c_void = yaml_realloc(
             *start,
-            ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
-                * 2_i64) as size_t,
+            (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char)
+                as libc::c_long)
+                .force_mul(2_i64)) as size_t,
         );
         *head = (new_start as *mut libc::c_char).wrapping_offset(
             (*head as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
@@ -134,8 +137,9 @@
                 as isize,
         ) as *mut libc::c_void;
         *end = (new_start as *mut libc::c_char).wrapping_offset(
-            ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
-                * 2_i64) as isize,
+            (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char)
+                as libc::c_long)
+                .force_mul(2_i64)) as isize,
         ) as *mut libc::c_void;
         *start = new_start;
     }
@@ -145,7 +149,7 @@
                 *start,
                 *head,
                 (*tail as *mut libc::c_char).c_offset_from(*head as *mut libc::c_char)
-                    as libc::c_long as libc::c_ulong,
+                    as libc::c_ulong,
             );
         }
         *tail = (*start as *mut libc::c_char).wrapping_offset(
@@ -220,13 +224,13 @@
             .input
             .string
             .end
-            .c_offset_from((*parser).input.string.current) as libc::c_long as size_t
+            .c_offset_from((*parser).input.string.current) as size_t
     {
         size = (*parser)
             .input
             .string
             .end
-            .c_offset_from((*parser).input.string.current) as libc::c_long as size_t;
+            .c_offset_from((*parser).input.string.current) as size_t;
     }
     memcpy(
         buffer as *mut libc::c_void,
@@ -374,7 +378,7 @@
         size,
     );
     let fresh153 = addr_of_mut!((*(*emitter).output.string.size_written));
-    *fresh153 = (*fresh153 as libc::c_ulong).wrapping_add(size) as size_t as size_t;
+    *fresh153 = (*fresh153 as libc::c_ulong).force_add(size) as size_t;
     1
 }
 
@@ -532,8 +536,8 @@
             if octet & 0xC0 != 0x80 {
                 return FAIL;
             }
-            value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
-            k = k.wrapping_add(1);
+            value = (value << 6).force_add((octet & 0x3F) as libc::c_uint);
+            k = k.force_add(1);
         }
         if !(width == 1
             || width == 2 && value >= 0x80
@@ -826,7 +830,7 @@
                 length = strlen(value as *mut libc::c_char) as libc::c_int;
             }
             if yaml_check_utf8(value, length as size_t).ok {
-                value_copy = yaml_malloc((length + 1) as size_t) as *mut yaml_char_t;
+                value_copy = yaml_malloc(length.force_add(1) as size_t) as *mut yaml_char_t;
                 memcpy(
                     value_copy as *mut libc::c_void,
                     value as *const libc::c_void,
@@ -1333,7 +1337,7 @@
                 length = strlen(value as *mut libc::c_char) as libc::c_int;
             }
             if yaml_check_utf8(value, length as size_t).ok {
-                value_copy = yaml_malloc((length + 1) as size_t) as *mut yaml_char_t;
+                value_copy = yaml_malloc(length.force_add(1) as size_t) as *mut yaml_char_t;
                 memcpy(
                     value_copy as *mut libc::c_void,
                     value as *const libc::c_void,
diff --git a/src/dumper.rs b/src/dumper.rs
index 47ebf3e..7d00cd8 100644
--- a/src/dumper.rs
+++ b/src/dumper.rs
@@ -1,6 +1,7 @@
 use crate::api::{yaml_free, yaml_malloc};
 use crate::externs::{memset, strcmp};
 use crate::fmt::WriteToPtr;
+use crate::ops::ForceMul as _;
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{
     yaml_anchors_t, yaml_char_t, yaml_document_t, yaml_emitter_t, yaml_event_t, yaml_mark_t,
@@ -116,15 +117,15 @@
                 let fresh1 = addr_of_mut!((*emitter).anchors);
                 *fresh1 = yaml_malloc(
                     (size_of::<yaml_anchors_t>() as libc::c_ulong)
-                        .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
-                            as libc::c_long as libc::c_ulong),
+                        .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
+                            as libc::c_ulong),
                 ) as *mut yaml_anchors_t;
                 memset(
                     (*emitter).anchors as *mut libc::c_void,
                     0,
                     (size_of::<yaml_anchors_t>() as libc::c_ulong)
-                        .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
-                            as libc::c_long as libc::c_ulong),
+                        .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
+                            as libc::c_ulong),
                 );
                 memset(
                     event as *mut libc::c_void,
diff --git a/src/emitter.rs b/src/emitter.rs
index 11f5cbd..a223b32 100644
--- a/src/emitter.rs
+++ b/src/emitter.rs
@@ -1,5 +1,6 @@
 use crate::api::{yaml_free, yaml_queue_extend, yaml_stack_extend, yaml_strdup};
 use crate::externs::{strcmp, strlen, strncmp};
+use crate::ops::{ForceAdd as _, ForceMul as _};
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{size_t, yaml_char_t, yaml_string_t};
 use crate::{
@@ -296,7 +297,9 @@
         if (*emitter).best_indent < 2 || (*emitter).best_indent > 9 {
             (*emitter).best_indent = 2;
         }
-        if (*emitter).best_width >= 0 && (*emitter).best_width <= (*emitter).best_indent * 2 {
+        if (*emitter).best_width >= 0
+            && (*emitter).best_width <= (*emitter).best_indent.force_mul(2)
+        {
             (*emitter).best_width = 80;
         }
         if (*emitter).best_width < 0 {
@@ -1045,45 +1048,36 @@
     let mut length: size_t = 0_u64;
     match (*event).type_ {
         YAML_ALIAS_EVENT => {
-            length = (length as libc::c_ulong).wrapping_add((*emitter).anchor_data.anchor_length)
-                as size_t as size_t;
+            length =
+                (length as libc::c_ulong).force_add((*emitter).anchor_data.anchor_length) as size_t;
         }
         YAML_SCALAR_EVENT => {
             if (*emitter).scalar_data.multiline {
                 return false;
             }
-            length = (length as libc::c_ulong).wrapping_add(
-                (*emitter)
-                    .anchor_data
-                    .anchor_length
-                    .wrapping_add((*emitter).tag_data.handle_length)
-                    .wrapping_add((*emitter).tag_data.suffix_length)
-                    .wrapping_add((*emitter).scalar_data.length),
-            ) as size_t as size_t;
+            length = (length as libc::c_ulong)
+                .force_add((*emitter).anchor_data.anchor_length)
+                .force_add((*emitter).tag_data.handle_length)
+                .force_add((*emitter).tag_data.suffix_length)
+                .force_add((*emitter).scalar_data.length) as size_t;
         }
         YAML_SEQUENCE_START_EVENT => {
             if !yaml_emitter_check_empty_sequence(emitter) {
                 return false;
             }
-            length = (length as libc::c_ulong).wrapping_add(
-                (*emitter)
-                    .anchor_data
-                    .anchor_length
-                    .wrapping_add((*emitter).tag_data.handle_length)
-                    .wrapping_add((*emitter).tag_data.suffix_length),
-            ) as size_t as size_t;
+            length = (length as libc::c_ulong)
+                .force_add((*emitter).anchor_data.anchor_length)
+                .force_add((*emitter).tag_data.handle_length)
+                .force_add((*emitter).tag_data.suffix_length) as size_t;
         }
         YAML_MAPPING_START_EVENT => {
             if !yaml_emitter_check_empty_mapping(emitter) {
                 return false;
             }
-            length = (length as libc::c_ulong).wrapping_add(
-                (*emitter)
-                    .anchor_data
-                    .anchor_length
-                    .wrapping_add((*emitter).tag_data.handle_length)
-                    .wrapping_add((*emitter).tag_data.suffix_length),
-            ) as size_t as size_t;
+            length = (length as libc::c_ulong)
+                .force_add((*emitter).anchor_data.anchor_length)
+                .force_add((*emitter).tag_data.handle_length)
+                .force_add((*emitter).tag_data.suffix_length) as size_t;
         }
         _ => return false,
     }
@@ -1379,8 +1373,7 @@
     }
     let fresh47 = addr_of_mut!((*emitter).anchor_data.anchor);
     *fresh47 = string.start;
-    (*emitter).anchor_data.anchor_length =
-        string.end.c_offset_from(string.start) as libc::c_long as size_t;
+    (*emitter).anchor_data.anchor_length = string.end.c_offset_from(string.start) as size_t;
     (*emitter).anchor_data.alias = alias;
     OK
 }
@@ -1398,7 +1391,7 @@
     tag_directive = (*emitter).tag_directives.start;
     while tag_directive != (*emitter).tag_directives.top {
         let prefix_length: size_t = strlen((*tag_directive).prefix as *mut libc::c_char);
-        if prefix_length < string.end.c_offset_from(string.start) as libc::c_long as size_t
+        if prefix_length < string.end.c_offset_from(string.start) as size_t
             && strncmp(
                 (*tag_directive).prefix as *mut libc::c_char,
                 string.start as *mut libc::c_char,
@@ -1412,7 +1405,7 @@
             let fresh49 = addr_of_mut!((*emitter).tag_data.suffix);
             *fresh49 = string.start.wrapping_offset(prefix_length as isize);
             (*emitter).tag_data.suffix_length = (string.end.c_offset_from(string.start)
-                as libc::c_long as libc::c_ulong)
+                as libc::c_ulong)
                 .wrapping_sub(prefix_length);
             return OK;
         }
@@ -1420,8 +1413,7 @@
     }
     let fresh50 = addr_of_mut!((*emitter).tag_data.suffix);
     *fresh50 = string.start;
-    (*emitter).tag_data.suffix_length =
-        string.end.c_offset_from(string.start) as libc::c_long as size_t;
+    (*emitter).tag_data.suffix_length = string.end.c_offset_from(string.start) as size_t;
     OK
 }
 
@@ -1827,7 +1819,7 @@
                 }
                 if PUT(
                     emitter,
-                    (value >> 4).wrapping_add(if (value >> 4) < 10 { b'0' } else { b'A' - 10 }),
+                    (value >> 4).force_add(if (value >> 4) < 10 { b'0' } else { b'A' - 10 }),
                 )
                 .fail
                 {
@@ -1835,7 +1827,7 @@
                 }
                 if PUT(
                     emitter,
-                    (value & 0x0F).wrapping_add(if (value & 0x0F) < 10 { b'0' } else { b'A' - 10 }),
+                    (value & 0x0F).force_add(if (value & 0x0F) < 10 { b'0' } else { b'A' - 10 }),
                 )
                 .fail
                 {
@@ -2053,7 +2045,7 @@
             k = 1;
             while k < width as libc::c_int {
                 octet = *string.pointer.wrapping_offset(k as isize);
-                value_0 = (value_0 << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
+                value_0 = (value_0 << 6).force_add((octet & 0x3F) as libc::c_uint);
                 k += 1;
             }
             string.pointer = string.pointer.wrapping_offset(width as isize);
diff --git a/src/lib.rs b/src/lib.rs
index aece24d..dc842af 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,7 +5,7 @@
 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
 
 #![no_std]
-#![doc(html_root_url = "https://docs.rs/unsafe-libyaml/0.2.9")]
+#![doc(html_root_url = "https://docs.rs/unsafe-libyaml/0.2.10")]
 #![allow(non_camel_case_types, non_snake_case)]
 #![warn(clippy::pedantic)]
 #![allow(
@@ -47,28 +47,42 @@
 mod libc {
     pub use core::ffi::c_void;
     pub use core::primitive::{
-        i32 as c_int, i64 as c_long, i8 as c_char, i8 as c_schar, u16 as c_ushort, u32 as c_uint,
-        u64 as c_ulong, u8 as c_uchar,
+        i32 as c_int, i64 as c_long, i8 as c_char, u32 as c_uint, u64 as c_ulong, u8 as c_uchar,
     };
 }
 
 #[macro_use]
 mod externs {
     use crate::libc;
+    use crate::ops::{die, ForceAdd as _, ForceInto as _};
     use alloc::alloc::{self as rust, Layout};
     use core::mem::{self, MaybeUninit};
     use core::ptr;
     use core::slice;
 
-    const HEADER: usize = mem::size_of::<usize>();
+    const HEADER: usize = {
+        let need_len = mem::size_of::<usize>();
+        // Round up to multiple of MALLOC_ALIGN.
+        (need_len + MALLOC_ALIGN - 1) & !(MALLOC_ALIGN - 1)
+    };
 
     // `max_align_t` may be bigger than this, but libyaml does not use `long
     // double` or u128.
-    const MALLOC_ALIGN: usize = mem::align_of::<usize>();
+    const MALLOC_ALIGN: usize = {
+        let int_align = mem::align_of::<libc::c_ulong>();
+        let ptr_align = mem::align_of::<usize>();
+        if int_align >= ptr_align {
+            int_align
+        } else {
+            ptr_align
+        }
+    };
 
     pub unsafe fn malloc(size: libc::c_ulong) -> *mut libc::c_void {
-        let size = HEADER + size as usize;
-        let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
+        let size = HEADER.force_add(size.force_into());
+        let layout = Layout::from_size_align(size, MALLOC_ALIGN)
+            .ok()
+            .unwrap_or_else(die);
         let memory = rust::alloc(layout);
         if memory.is_null() {
             rust::handle_alloc_error(layout);
@@ -81,11 +95,13 @@
         let mut memory = ptr.cast::<u8>().sub(HEADER);
         let size = memory.cast::<usize>().read();
         let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
-        let new_size = HEADER + new_size as usize;
+        let new_size = HEADER.force_add(new_size.force_into());
+        let new_layout = Layout::from_size_align(new_size, MALLOC_ALIGN)
+            .ok()
+            .unwrap_or_else(die);
         memory = rust::realloc(memory, layout, new_size);
         if memory.is_null() {
-            let layout = Layout::from_size_align_unchecked(new_size, MALLOC_ALIGN);
-            rust::handle_alloc_error(layout);
+            rust::handle_alloc_error(new_layout);
         }
         memory.cast::<usize>().write(new_size);
         memory.add(HEADER).cast()
@@ -263,6 +279,7 @@
 mod dumper;
 mod emitter;
 mod loader;
+mod ops;
 mod parser;
 mod reader;
 mod scanner;
diff --git a/src/ops.rs b/src/ops.rs
new file mode 100644
index 0000000..4597d3d
--- /dev/null
+++ b/src/ops.rs
@@ -0,0 +1,111 @@
+pub(crate) trait ForceAdd: Sized {
+    fn force_add(self, rhs: Self) -> Self;
+}
+
+impl ForceAdd for u8 {
+    fn force_add(self, rhs: Self) -> Self {
+        self.checked_add(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceAdd for i32 {
+    fn force_add(self, rhs: Self) -> Self {
+        self.checked_add(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceAdd for u32 {
+    fn force_add(self, rhs: Self) -> Self {
+        self.checked_add(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceAdd for u64 {
+    fn force_add(self, rhs: Self) -> Self {
+        self.checked_add(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceAdd for usize {
+    fn force_add(self, rhs: Self) -> Self {
+        self.checked_add(rhs).unwrap_or_else(die)
+    }
+}
+
+pub(crate) trait ForceMul: Sized {
+    fn force_mul(self, rhs: Self) -> Self;
+}
+
+impl ForceMul for i32 {
+    fn force_mul(self, rhs: Self) -> Self {
+        self.checked_mul(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceMul for i64 {
+    fn force_mul(self, rhs: Self) -> Self {
+        self.checked_mul(rhs).unwrap_or_else(die)
+    }
+}
+
+impl ForceMul for u64 {
+    fn force_mul(self, rhs: Self) -> Self {
+        self.checked_mul(rhs).unwrap_or_else(die)
+    }
+}
+
+pub(crate) trait ForceInto {
+    fn force_into<U>(self) -> U
+    where
+        Self: TryInto<U>;
+}
+
+impl<T> ForceInto for T {
+    fn force_into<U>(self) -> U
+    where
+        Self: TryInto<U>,
+    {
+        <Self as TryInto<U>>::try_into(self)
+            .ok()
+            .unwrap_or_else(die)
+    }
+}
+
+// Deterministically abort on arithmetic overflow, instead of wrapping and
+// continuing with invalid behavior.
+//
+// This is impossible or nearly impossible to hit as the arithmetic computations
+// in libyaml are all related to either:
+//
+//  - small integer processing (ascii, hex digits)
+//  - allocation sizing
+//
+// and the only allocations in libyaml are for fixed-sized objects and
+// geometrically growing buffers with a growth factor of 2. So in order for an
+// allocation computation to overflow usize, the previous allocation for that
+// container must have been filled to a size of usize::MAX/2, which is an
+// allocation that would have failed in the allocator. But we check for this to
+// be pedantic and to find out if it ever does happen.
+//
+// No-std abort is implemented using a double panic. On most platforms the
+// current mechanism for this is for core::intrinsics::abort to invoke an
+// invalid instruction. On Unix, the process will probably terminate with a
+// signal like SIGABRT, SIGILL, SIGTRAP, SIGSEGV or SIGBUS. The precise
+// behaviour is not guaranteed and not stable, but is safe.
+#[cold]
+pub(crate) fn die<T>() -> T {
+    struct PanicAgain;
+
+    impl Drop for PanicAgain {
+        fn drop(&mut self) {
+            panic!("arithmetic overflow");
+        }
+    }
+
+    fn do_die() -> ! {
+        let _panic_again = PanicAgain;
+        panic!("arithmetic overflow");
+    }
+
+    do_die();
+}
diff --git a/src/parser.rs b/src/parser.rs
index c4f4f35..d40e5d2 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,5 +1,6 @@
 use crate::api::{yaml_free, yaml_malloc, yaml_stack_extend, yaml_strdup};
 use crate::externs::{memcpy, memset, strcmp, strlen};
+use crate::ops::ForceAdd as _;
 use crate::scanner::yaml_parser_fetch_more_tokens;
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{size_t, yaml_char_t};
@@ -504,9 +505,8 @@
                             let prefix_len: size_t =
                                 strlen((*tag_directive).prefix as *mut libc::c_char);
                             let suffix_len: size_t = strlen(tag_suffix as *mut libc::c_char);
-                            tag = yaml_malloc(
-                                prefix_len.wrapping_add(suffix_len).wrapping_add(1_u64),
-                            ) as *mut yaml_char_t;
+                            tag = yaml_malloc(prefix_len.force_add(suffix_len).force_add(1_u64))
+                                as *mut yaml_char_t;
                             memcpy(
                                 tag as *mut libc::c_void,
                                 (*tag_directive).prefix as *const libc::c_void,
@@ -517,8 +517,7 @@
                                 tag_suffix as *const libc::c_void,
                                 suffix_len,
                             );
-                            *tag.wrapping_offset(prefix_len.wrapping_add(suffix_len) as isize) =
-                                b'\0';
+                            *tag.wrapping_offset(prefix_len.force_add(suffix_len) as isize) = b'\0';
                             yaml_free(tag_handle as *mut libc::c_void);
                             yaml_free(tag_suffix as *mut libc::c_void);
                             tag_suffix = ptr::null_mut::<yaml_char_t>();
diff --git a/src/reader.rs b/src/reader.rs
index 264ad92..5adc54a 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -1,4 +1,5 @@
 use crate::externs::{memcmp, memmove};
+use crate::ops::ForceAdd as _;
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{size_t, yaml_char_t};
 use crate::{
@@ -52,7 +53,7 @@
         let fresh1 = addr_of_mut!((*parser).raw_buffer.pointer);
         *fresh1 = (*fresh1).wrapping_offset(2_isize);
         let fresh2 = addr_of_mut!((*parser).offset);
-        *fresh2 = (*fresh2 as libc::c_ulong).wrapping_add(2_u64) as size_t as size_t;
+        *fresh2 = (*fresh2 as libc::c_ulong).force_add(2_u64) as size_t;
     } else if (*parser)
         .raw_buffer
         .last
@@ -68,7 +69,7 @@
         let fresh3 = addr_of_mut!((*parser).raw_buffer.pointer);
         *fresh3 = (*fresh3).wrapping_offset(2_isize);
         let fresh4 = addr_of_mut!((*parser).offset);
-        *fresh4 = (*fresh4 as libc::c_ulong).wrapping_add(2_u64) as size_t as size_t;
+        *fresh4 = (*fresh4 as libc::c_ulong).force_add(2_u64) as size_t;
     } else if (*parser)
         .raw_buffer
         .last
@@ -84,7 +85,7 @@
         let fresh5 = addr_of_mut!((*parser).raw_buffer.pointer);
         *fresh5 = (*fresh5).wrapping_offset(3_isize);
         let fresh6 = addr_of_mut!((*parser).offset);
-        *fresh6 = (*fresh6 as libc::c_ulong).wrapping_add(3_u64) as size_t as size_t;
+        *fresh6 = (*fresh6 as libc::c_ulong).force_add(3_u64) as size_t;
     } else {
         (*parser).encoding = YAML_UTF8_ENCODING;
     }
@@ -129,7 +130,7 @@
         (*parser)
             .raw_buffer
             .end
-            .c_offset_from((*parser).raw_buffer.last) as libc::c_long as size_t,
+            .c_offset_from((*parser).raw_buffer.last) as size_t,
         addr_of_mut!(size_read),
     ) == 0
     {
@@ -171,8 +172,7 @@
         let size: size_t = (*parser)
             .buffer
             .last
-            .c_offset_from((*parser).buffer.pointer) as libc::c_long
-            as size_t;
+            .c_offset_from((*parser).buffer.pointer) as size_t;
         memmove(
             (*parser).buffer.start as *mut libc::c_void,
             (*parser).buffer.pointer as *const libc::c_void,
@@ -208,7 +208,7 @@
                 .raw_buffer
                 .last
                 .c_offset_from((*parser).raw_buffer.pointer)
-                as libc::c_long as size_t;
+                as size_t;
             match (*parser).encoding {
                 YAML_UTF8_ENCODING => {
                     octet = *(*parser).raw_buffer.pointer;
@@ -262,12 +262,12 @@
                                     parser,
                                     b"invalid trailing UTF-8 octet\0" as *const u8
                                         as *const libc::c_char,
-                                    (*parser).offset.wrapping_add(k),
+                                    (*parser).offset.force_add(k),
                                     octet as libc::c_int,
                                 );
                             }
-                            value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
-                            k = k.wrapping_add(1);
+                            value = (value << 6).force_add((octet & 0x3F) as libc::c_uint);
+                            k = k.force_add(1);
                         }
                         if !(width == 1
                             || width == 2 && value >= 0x80
@@ -360,13 +360,13 @@
                                         parser,
                                         b"expected low surrogate area\0" as *const u8
                                             as *const libc::c_char,
-                                        (*parser).offset.wrapping_add(2_u64),
+                                        (*parser).offset.force_add(2_u64),
                                         value2 as libc::c_int,
                                     );
                                 }
                                 value = 0x10000_u32
-                                    .wrapping_add((value & 0x3FF) << 10)
-                                    .wrapping_add(value2 & 0x3FF);
+                                    .force_add((value & 0x3FF) << 10)
+                                    .force_add(value2 & 0x3FF);
                             }
                         } else {
                             width = 2;
@@ -397,8 +397,7 @@
             let fresh14 = addr_of_mut!((*parser).raw_buffer.pointer);
             *fresh14 = (*fresh14).wrapping_offset(width as isize);
             let fresh15 = addr_of_mut!((*parser).offset);
-            *fresh15 = (*fresh15 as libc::c_ulong).wrapping_add(width as libc::c_ulong) as size_t
-                as size_t;
+            *fresh15 = (*fresh15 as libc::c_ulong).force_add(width as libc::c_ulong) as size_t;
             if value <= 0x7F {
                 let fresh16 = addr_of_mut!((*parser).buffer.last);
                 let fresh17 = *fresh16;
@@ -408,44 +407,44 @@
                 let fresh18 = addr_of_mut!((*parser).buffer.last);
                 let fresh19 = *fresh18;
                 *fresh18 = (*fresh18).wrapping_offset(1);
-                *fresh19 = 0xC0_u32.wrapping_add(value >> 6) as yaml_char_t;
+                *fresh19 = 0xC0_u32.force_add(value >> 6) as yaml_char_t;
                 let fresh20 = addr_of_mut!((*parser).buffer.last);
                 let fresh21 = *fresh20;
                 *fresh20 = (*fresh20).wrapping_offset(1);
-                *fresh21 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                *fresh21 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
             } else if value <= 0xFFFF {
                 let fresh22 = addr_of_mut!((*parser).buffer.last);
                 let fresh23 = *fresh22;
                 *fresh22 = (*fresh22).wrapping_offset(1);
-                *fresh23 = 0xE0_u32.wrapping_add(value >> 12) as yaml_char_t;
+                *fresh23 = 0xE0_u32.force_add(value >> 12) as yaml_char_t;
                 let fresh24 = addr_of_mut!((*parser).buffer.last);
                 let fresh25 = *fresh24;
                 *fresh24 = (*fresh24).wrapping_offset(1);
-                *fresh25 = 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+                *fresh25 = 0x80_u32.force_add(value >> 6 & 0x3F) as yaml_char_t;
                 let fresh26 = addr_of_mut!((*parser).buffer.last);
                 let fresh27 = *fresh26;
                 *fresh26 = (*fresh26).wrapping_offset(1);
-                *fresh27 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                *fresh27 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
             } else {
                 let fresh28 = addr_of_mut!((*parser).buffer.last);
                 let fresh29 = *fresh28;
                 *fresh28 = (*fresh28).wrapping_offset(1);
-                *fresh29 = 0xF0_u32.wrapping_add(value >> 18) as yaml_char_t;
+                *fresh29 = 0xF0_u32.force_add(value >> 18) as yaml_char_t;
                 let fresh30 = addr_of_mut!((*parser).buffer.last);
                 let fresh31 = *fresh30;
                 *fresh30 = (*fresh30).wrapping_offset(1);
-                *fresh31 = 0x80_u32.wrapping_add(value >> 12 & 0x3F) as yaml_char_t;
+                *fresh31 = 0x80_u32.force_add(value >> 12 & 0x3F) as yaml_char_t;
                 let fresh32 = addr_of_mut!((*parser).buffer.last);
                 let fresh33 = *fresh32;
                 *fresh32 = (*fresh32).wrapping_offset(1);
-                *fresh33 = 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+                *fresh33 = 0x80_u32.force_add(value >> 6 & 0x3F) as yaml_char_t;
                 let fresh34 = addr_of_mut!((*parser).buffer.last);
                 let fresh35 = *fresh34;
                 *fresh34 = (*fresh34).wrapping_offset(1);
-                *fresh35 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                *fresh35 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
             }
             let fresh36 = addr_of_mut!((*parser).unread);
-            *fresh36 = (*fresh36).wrapping_add(1);
+            *fresh36 = (*fresh36).force_add(1);
         }
         if (*parser).eof {
             let fresh37 = addr_of_mut!((*parser).buffer.last);
@@ -453,7 +452,7 @@
             *fresh37 = (*fresh37).wrapping_offset(1);
             *fresh38 = b'\0';
             let fresh39 = addr_of_mut!((*parser).unread);
-            *fresh39 = (*fresh39).wrapping_add(1);
+            *fresh39 = (*fresh39).force_add(1);
             return OK;
         }
     }
diff --git a/src/scanner.rs b/src/scanner.rs
index 175719c..4e53dad 100644
--- a/src/scanner.rs
+++ b/src/scanner.rs
@@ -3,6 +3,7 @@
     yaml_string_join,
 };
 use crate::externs::{memcpy, memmove, memset, strcmp, strlen};
+use crate::ops::{ForceAdd as _, ForceMul as _};
 use crate::reader::yaml_parser_update_buffer;
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::{ptrdiff_t, size_t, yaml_char_t, yaml_string_t, NULL_STRING};
@@ -31,24 +32,24 @@
 
 unsafe fn SKIP(parser: *mut yaml_parser_t) {
     let width = WIDTH!((*parser).buffer);
-    (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
-    (*parser).mark.column = (*parser).mark.column.wrapping_add(1);
+    (*parser).mark.index = (*parser).mark.index.force_add(width as u64);
+    (*parser).mark.column = (*parser).mark.column.force_add(1);
     (*parser).unread = (*parser).unread.wrapping_sub(1);
     (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(width as isize);
 }
 
 unsafe fn SKIP_LINE(parser: *mut yaml_parser_t) {
     if IS_CRLF!((*parser).buffer) {
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+        (*parser).mark.index = (*parser).mark.index.force_add(2);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(2);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
     } else if IS_BREAK!((*parser).buffer) {
         let width = WIDTH!((*parser).buffer);
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
+        (*parser).mark.index = (*parser).mark.index.force_add(width as u64);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(1);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(width as isize);
     };
@@ -58,8 +59,8 @@
     STRING_EXTEND!(*string);
     let width = WIDTH!((*parser).buffer);
     COPY!(*string, (*parser).buffer);
-    (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
-    (*parser).mark.column = (*parser).mark.column.wrapping_add(1);
+    (*parser).mark.index = (*parser).mark.index.force_add(width as u64);
+    (*parser).mark.column = (*parser).mark.column.force_add(1);
     (*parser).unread = (*parser).unread.wrapping_sub(1);
 }
 
@@ -69,25 +70,25 @@
         *(*string).pointer = b'\n';
         (*string).pointer = (*string).pointer.wrapping_offset(1);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+        (*parser).mark.index = (*parser).mark.index.force_add(2);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(2);
     } else if CHECK_AT!((*parser).buffer, b'\r', 0) || CHECK_AT!((*parser).buffer, b'\n', 0) {
         *(*string).pointer = b'\n';
         (*string).pointer = (*string).pointer.wrapping_offset(1);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(1);
+        (*parser).mark.index = (*parser).mark.index.force_add(1);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(1);
     } else if CHECK_AT!((*parser).buffer, b'\xC2', 0) && CHECK_AT!((*parser).buffer, b'\x85', 1) {
         *(*string).pointer = b'\n';
         (*string).pointer = (*string).pointer.wrapping_offset(1);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+        (*parser).mark.index = (*parser).mark.index.force_add(2);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(1);
     } else if CHECK_AT!((*parser).buffer, b'\xE2', 0)
         && CHECK_AT!((*parser).buffer, b'\x80', 1)
@@ -102,9 +103,9 @@
         *(*string).pointer = *(*parser).buffer.pointer;
         (*string).pointer = (*string).pointer.wrapping_offset(1);
         (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
-        (*parser).mark.index = (*parser).mark.index.wrapping_add(3);
+        (*parser).mark.index = (*parser).mark.index.force_add(3);
         (*parser).mark.column = 0;
-        (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+        (*parser).mark.line = (*parser).mark.line.force_add(1);
         (*parser).unread = (*parser).unread.wrapping_sub(1);
     };
 }
@@ -152,7 +153,7 @@
     *token = DEQUEUE!((*parser).tokens);
     (*parser).token_available = false;
     let fresh2 = addr_of_mut!((*parser).tokens_parsed);
-    *fresh2 = (*fresh2).wrapping_add(1);
+    *fresh2 = (*fresh2).force_add(1);
     if (*token).type_ == YAML_STREAM_END_TOKEN {
         (*parser).stream_end_produced = true;
     }
@@ -337,7 +338,7 @@
     while simple_key != (*parser).simple_keys.top {
         if (*simple_key).possible
             && ((*simple_key).mark.line < (*parser).mark.line
-                || (*simple_key).mark.index.wrapping_add(1024_u64) < (*parser).mark.index)
+                || (*simple_key).mark.index.force_add(1024_u64) < (*parser).mark.index)
         {
             if (*simple_key).required {
                 yaml_parser_set_scanner_error(
@@ -362,10 +363,9 @@
         let simple_key = yaml_simple_key_t {
             possible: true,
             required,
-            token_number: (*parser)
-                .tokens_parsed
-                .wrapping_add((*parser).tokens.tail.c_offset_from((*parser).tokens.head)
-                    as libc::c_long as libc::c_ulong),
+            token_number: (*parser).tokens_parsed.force_add(
+                (*parser).tokens.tail.c_offset_from((*parser).tokens.head) as libc::c_ulong,
+            ),
             mark: (*parser).mark,
         };
         if yaml_parser_remove_simple_key(parser).fail {
@@ -517,7 +517,7 @@
     if (*parser).mark.column != 0_u64 {
         (*parser).mark.column = 0_u64;
         let fresh22 = addr_of_mut!((*parser).mark.line);
-        *fresh22 = (*fresh22).wrapping_add(1);
+        *fresh22 = (*fresh22).force_add(1);
     }
     yaml_parser_unroll_indent(parser, -1_i64);
     if yaml_parser_remove_simple_key(parser).fail {
@@ -1168,7 +1168,7 @@
         return FAIL;
     }
     while IS_DIGIT!((*parser).buffer) {
-        length = length.wrapping_add(1);
+        length = length.force_add(1);
         if length > MAX_NUMBER_LENGTH {
             yaml_parser_set_scanner_error(
                 parser,
@@ -1178,7 +1178,7 @@
             );
             return FAIL;
         }
-        value = value * 10 + AS_DIGIT!((*parser).buffer);
+        value = value.force_mul(10).force_add(AS_DIGIT!((*parser).buffer));
         SKIP(parser);
         if CACHE(parser, 1_u64).fail {
             return FAIL;
@@ -1592,7 +1592,7 @@
                 return FAIL;
             }
             _ => {
-                if string.end.c_offset_from(string.start) as libc::c_long as size_t <= length {
+                if string.end.c_offset_from(string.start) as size_t <= length {
                     yaml_string_extend(
                         addr_of_mut!(string.start),
                         addr_of_mut!(string.pointer),
@@ -1654,7 +1654,7 @@
                         } else {
                             READ!(parser, string);
                         }
-                        length = length.wrapping_add(1);
+                        length = length.force_add(1);
                         if CACHE(parser, 1_u64).fail {
                             current_block = 15265153392498847348;
                             continue 'c_21953;
@@ -1992,7 +1992,6 @@
                                                 *fresh479 = string.start;
                                                 (*token).data.scalar.length =
                                                     string.pointer.c_offset_from(string.start)
-                                                        as libc::c_long
                                                         as size_t;
                                                 (*token).data.scalar.style = if literal {
                                                     YAML_LITERAL_SCALAR_STYLE
@@ -2314,12 +2313,12 @@
                                     current_block = 8114179180390253173;
                                     break 's_58;
                                 } else {
-                                    value = (value << 4).wrapping_add(AS_HEX_AT!(
+                                    value = (value << 4).force_add(AS_HEX_AT!(
                                         (*parser).buffer,
                                         k as isize
                                     )
                                         as libc::c_uint);
-                                    k = k.wrapping_add(1);
+                                    k = k.force_add(1);
                                 }
                             }
                             if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
@@ -2341,41 +2340,41 @@
                                 } else if value <= 0x7FF {
                                     let fresh574 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh574 = 0xC0_u32.wrapping_add(value >> 6) as yaml_char_t;
+                                    *fresh574 = 0xC0_u32.force_add(value >> 6) as yaml_char_t;
                                     let fresh575 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh575 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                                    *fresh575 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
                                 } else if value <= 0xFFFF {
                                     let fresh576 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh576 = 0xE0_u32.wrapping_add(value >> 12) as yaml_char_t;
+                                    *fresh576 = 0xE0_u32.force_add(value >> 12) as yaml_char_t;
                                     let fresh577 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
                                     *fresh577 =
-                                        0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+                                        0x80_u32.force_add(value >> 6 & 0x3F) as yaml_char_t;
                                     let fresh578 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh578 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                                    *fresh578 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
                                 } else {
                                     let fresh579 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh579 = 0xF0_u32.wrapping_add(value >> 18) as yaml_char_t;
+                                    *fresh579 = 0xF0_u32.force_add(value >> 18) as yaml_char_t;
                                     let fresh580 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
                                     *fresh580 =
-                                        0x80_u32.wrapping_add(value >> 12 & 0x3F) as yaml_char_t;
+                                        0x80_u32.force_add(value >> 12 & 0x3F) as yaml_char_t;
                                     let fresh581 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
                                     *fresh581 =
-                                        0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+                                        0x80_u32.force_add(value >> 6 & 0x3F) as yaml_char_t;
                                     let fresh582 = string.pointer;
                                     string.pointer = string.pointer.wrapping_offset(1);
-                                    *fresh582 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+                                    *fresh582 = 0x80_u32.force_add(value & 0x3F) as yaml_char_t;
                                 }
                                 k = 0_u64;
                                 while k < code_length {
                                     SKIP(parser);
-                                    k = k.wrapping_add(1);
+                                    k = k.force_add(1);
                                 }
                             }
                         }
@@ -2462,8 +2461,7 @@
         (*token).end_mark = end_mark;
         let fresh716 = addr_of_mut!((*token).data.scalar.value);
         *fresh716 = string.start;
-        (*token).data.scalar.length =
-            string.pointer.c_offset_from(string.start) as libc::c_long as size_t;
+        (*token).data.scalar.length = string.pointer.c_offset_from(string.start) as size_t;
         (*token).data.scalar.style = if single {
             YAML_SINGLE_QUOTED_SCALAR_STYLE
         } else {
@@ -2644,8 +2642,7 @@
         (*token).end_mark = end_mark;
         let fresh842 = addr_of_mut!((*token).data.scalar.value);
         *fresh842 = string.start;
-        (*token).data.scalar.length =
-            string.pointer.c_offset_from(string.start) as libc::c_long as size_t;
+        (*token).data.scalar.length = string.pointer.c_offset_from(string.start) as size_t;
         (*token).data.scalar.style = YAML_PLAIN_SCALAR_STYLE;
         if leading_blanks {
             (*parser).simple_key_allowed = true;
diff --git a/src/writer.rs b/src/writer.rs
index 11405bc..730c927 100644
--- a/src/writer.rs
+++ b/src/writer.rs
@@ -1,3 +1,4 @@
+use crate::ops::ForceAdd as _;
 use crate::success::{Success, FAIL, OK};
 use crate::yaml::size_t;
 use crate::{
@@ -35,7 +36,7 @@
             (*emitter)
                 .buffer
                 .last
-                .c_offset_from((*emitter).buffer.start) as libc::c_long as size_t,
+                .c_offset_from((*emitter).buffer.start) as size_t,
         ) != 0
         {
             let fresh3 = addr_of_mut!((*emitter).buffer.last);
@@ -90,8 +91,8 @@
         k = 1_u64;
         while k < width as libc::c_ulong {
             octet = *(*emitter).buffer.pointer.wrapping_offset(k as isize);
-            value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
-            k = k.wrapping_add(1);
+            value = (value << 6).force_add((octet & 0x3F) as libc::c_uint);
+            k = k.force_add(1);
         }
         let fresh5 = addr_of_mut!((*emitter).buffer.pointer);
         *fresh5 = (*fresh5).wrapping_offset(width as isize);
@@ -105,14 +106,14 @@
         } else {
             value = value.wrapping_sub(0x10000);
             *(*emitter).raw_buffer.last.wrapping_offset(high as isize) =
-                0xD8_u32.wrapping_add(value >> 18) as libc::c_uchar;
+                0xD8_u32.force_add(value >> 18) as libc::c_uchar;
             *(*emitter).raw_buffer.last.wrapping_offset(low as isize) =
                 (value >> 10 & 0xFF) as libc::c_uchar;
             *(*emitter)
                 .raw_buffer
                 .last
                 .wrapping_offset((high + 2) as isize) =
-                0xDC_u32.wrapping_add(value >> 8 & 0xFF) as libc::c_uchar;
+                0xDC_u32.force_add(value >> 8 & 0xFF) as libc::c_uchar;
             *(*emitter)
                 .raw_buffer
                 .last
@@ -127,7 +128,7 @@
         (*emitter)
             .raw_buffer
             .last
-            .c_offset_from((*emitter).raw_buffer.start) as libc::c_long as size_t,
+            .c_offset_from((*emitter).raw_buffer.start) as size_t,
     ) != 0
     {
         let fresh8 = addr_of_mut!((*emitter).buffer.last);
diff --git a/src/yaml.rs b/src/yaml.rs
index dfffe9c..ec05a80 100644
--- a/src/yaml.rs
+++ b/src/yaml.rs
@@ -2,11 +2,7 @@
 use core::ops::Deref;
 use core::ptr::{self, addr_of};
 
-pub use self::{
-    yaml_break_t::*, yaml_emitter_state_t::*, yaml_encoding_t::*, yaml_error_type_t::*,
-    yaml_event_type_t::*, yaml_mapping_style_t::*, yaml_node_type_t::*, yaml_parser_state_t::*,
-    yaml_scalar_style_t::*, yaml_sequence_style_t::*, yaml_token_type_t::*,
-};
+pub use self::{yaml_encoding_t::*, yaml_event_type_t::*, yaml_node_type_t::*};
 pub use core::primitive::{i64 as ptrdiff_t, u64 as size_t, u8 as yaml_char_t};
 
 /// The version directive data.