diff --git a/src/api.rs b/src/api.rs index 531b6b9..7b599ba 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,7 +54,7 @@ pub(crate) unsafe fn yaml_string_extend( ) { 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) @@ -62,8 +63,9 @@ pub(crate) unsafe fn yaml_string_extend( (*end).c_offset_from(*start) as libc::c_long 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; } @@ -99,16 +101,16 @@ pub(crate) unsafe fn yaml_stack_extend( ) { 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 @@ pub(crate) unsafe fn yaml_queue_extend( 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 @@ pub(crate) unsafe fn yaml_queue_extend( 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; } @@ -374,7 +378,7 @@ unsafe fn yaml_string_write_handler( size, ); let fresh153 = addr_of_mut!((*(*emitter).output.string.size_written)); - *fresh153 = (*fresh153 as libc::c_ulong).wrapping_add(size) as size_t; + *fresh153 = (*fresh153 as libc::c_ulong).force_add(size) as size_t; 1 } @@ -532,8 +536,8 @@ unsafe fn yaml_check_utf8(start: *const yaml_char_t, length: size_t) -> Success 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 @@ pub unsafe fn yaml_scalar_event_initialize( 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 @@ pub unsafe fn yaml_document_add_scalar( 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..d023732 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,14 +117,14 @@ pub unsafe fn yaml_emitter_dump( let fresh1 = addr_of_mut!((*emitter).anchors); *fresh1 = yaml_malloc( (size_of::() as libc::c_ulong) - .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start) + .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_long as libc::c_ulong), ) as *mut yaml_anchors_t; memset( (*emitter).anchors as *mut libc::c_void, 0, (size_of::() as libc::c_ulong) - .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start) + .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_long as libc::c_ulong), ); memset( diff --git a/src/emitter.rs b/src/emitter.rs index 27b9b26..0e79787 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 @@ unsafe fn yaml_emitter_emit_stream_start( 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 @@ unsafe fn yaml_emitter_check_simple_key(emitter: *mut yaml_emitter_t) -> bool { 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; + 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; + 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; + 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; + 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, } @@ -1825,7 +1819,7 @@ unsafe fn yaml_emitter_write_tag_content( } 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 { @@ -1833,7 +1827,7 @@ unsafe fn yaml_emitter_write_tag_content( } 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 { @@ -2051,7 +2045,7 @@ unsafe fn yaml_emitter_write_double_quoted_scalar( 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 44c608c..6865d9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -262,6 +262,7 @@ mod api; 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..a3b906c --- /dev/null +++ b/src/ops.rs @@ -0,0 +1,88 @@ +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) + } +} + +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) + } +} + +// 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 { + 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 @@ unsafe fn yaml_parser_parse_node( 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 @@ unsafe fn yaml_parser_parse_node( 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::(); diff --git a/src/reader.rs b/src/reader.rs index 3877f60..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 @@ unsafe fn yaml_parser_determine_encoding(parser: *mut yaml_parser_t) -> Success 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; + *fresh2 = (*fresh2 as libc::c_ulong).force_add(2_u64) as size_t; } else if (*parser) .raw_buffer .last @@ -68,7 +69,7 @@ unsafe fn yaml_parser_determine_encoding(parser: *mut yaml_parser_t) -> Success 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; + *fresh4 = (*fresh4 as libc::c_ulong).force_add(2_u64) as size_t; } else if (*parser) .raw_buffer .last @@ -84,7 +85,7 @@ unsafe fn yaml_parser_determine_encoding(parser: *mut yaml_parser_t) -> Success 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; + *fresh6 = (*fresh6 as libc::c_ulong).force_add(3_u64) as size_t; } else { (*parser).encoding = YAML_UTF8_ENCODING; } @@ -261,12 +262,12 @@ pub(crate) unsafe fn yaml_parser_update_buffer( 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 @@ -359,13 +360,13 @@ pub(crate) unsafe fn yaml_parser_update_buffer( 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; @@ -396,7 +397,7 @@ pub(crate) unsafe fn yaml_parser_update_buffer( 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; + *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; @@ -406,44 +407,44 @@ pub(crate) unsafe fn yaml_parser_update_buffer( 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); @@ -451,7 +452,7 @@ pub(crate) unsafe fn yaml_parser_update_buffer( *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 e99f83e..c7359e4 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -3,6 +3,7 @@ use crate::api::{ 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 CACHE(parser: *mut yaml_parser_t, length: size_t) -> Success { 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 @@ unsafe fn READ(parser: *mut yaml_parser_t, string: *mut yaml_string_t) { 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 @@ unsafe fn READ_LINE(parser: *mut yaml_parser_t, string: *mut yaml_string_t) { *(*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 @@ unsafe fn READ_LINE(parser: *mut yaml_parser_t, string: *mut yaml_string_t) { *(*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 @@ pub unsafe fn yaml_parser_scan(parser: *mut yaml_parser_t, token: *mut yaml_toke *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 @@ unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success { 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( @@ -364,7 +365,7 @@ unsafe fn yaml_parser_save_simple_key(parser: *mut yaml_parser_t) -> Success { required, token_number: (*parser) .tokens_parsed - .wrapping_add((*parser).tokens.tail.c_offset_from((*parser).tokens.head) + .force_add((*parser).tokens.tail.c_offset_from((*parser).tokens.head) as libc::c_long as libc::c_ulong), mark: (*parser).mark, }; @@ -517,7 +518,7 @@ unsafe fn yaml_parser_fetch_stream_end(parser: *mut yaml_parser_t) -> Success { 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 +1169,7 @@ unsafe fn yaml_parser_scan_version_directive_number( 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 +1179,7 @@ unsafe fn yaml_parser_scan_version_directive_number( ); 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; @@ -1654,7 +1655,7 @@ unsafe fn yaml_parser_scan_tag_uri( } 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; @@ -2313,12 +2314,12 @@ unsafe fn yaml_parser_scan_flow_scalar( 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 { @@ -2340,41 +2341,41 @@ unsafe fn yaml_parser_scan_flow_scalar( } 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); } } } diff --git a/src/writer.rs b/src/writer.rs index 4a62f9e..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::{ @@ -90,8 +91,8 @@ pub unsafe fn yaml_emitter_flush(emitter: *mut yaml_emitter_t) -> Success { 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 @@ pub unsafe fn yaml_emitter_flush(emitter: *mut yaml_emitter_t) -> Success { } 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