Skip to content

Commit

Permalink
Merge branch 'master' into swaystar123-fix-buffer-overflow-bytecode-s…
Browse files Browse the repository at this point in the history
…wap-configs
  • Loading branch information
bitzoic authored Aug 1, 2024
2 parents 534d758 + ddfe684 commit a5f5696
Show file tree
Hide file tree
Showing 19 changed files with 1,064 additions and 369 deletions.
38 changes: 37 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Description of the upcoming release here.
- [#259](https://github.com/FuelLabs/sway-libs/pull/259) Adds a new upgradability library, including associated tests and documentation.
- [#265](https://github.com/FuelLabs/sway-libs/pull/265) Adds the `SetMetadataEvent` and emits `SetMetadataEvent` when the `_set_metadata()` function is called.
- [#270](https://github.com/FuelLabs/sway-libs/pull/270) Adds `OrdEq` functionality to Signed Integers.
- [#272](https://github.com/FuelLabs/sway-libs/pull/272) Adds the `TryFrom` implementation from signed integers to unsigned integers.

### Changed

Expand All @@ -26,22 +27,57 @@ Description of the upcoming release here.
- [#262](https://github.com/FuelLabs/sway-libs/pull/262) Fixes incorrect ordering comparison for IFP64, IFP128 and IFP256.
- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I256`'s returned bits.
- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I128` and `I256`'s zero or "indent" value.
- [#268](https://github.com/FuelLabs/sway-libs/pull/268) Fixes subtraction involving negative numbers for `I8`, `I16`, `I32`, `I64`, `I128`, and `I256`.
- [#272](https://github.com/FuelLabs/sway-libs/pull/272) Fixes `From` implementations for Signed Integers with `TryFrom`.
- [#273](https://github.com/FuelLabs/sway-libs/pull/273) Fixes negative from implementations for Signed Integers.
- [#274](https://github.com/FuelLabs/sway-libs/pull/274) Fixes the `swap_configurables()` function to correctly handle the case where the bytecode is too large to fit in the buffer.

#### Breaking

- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Removes the `TwosComplement` trait in favor of `WrappingNeg`.

The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types.
The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types.

Before:

```sway
let my_i8 = i8::zero();
let twos_complement = my_i8.twos_complement();
```

After:

```sway
let my_i8 = i8::zero();
let wrapping_neg = my_i8.wrapping_neg();
```

- [#272](https://github.com/FuelLabs/sway-libs/pull/272) The `From` implementation for all signed integers to their respective unsigned integer has been removed. The `TryFrom` implementation has been added in its place.

Before:

```sway
let my_i8: I8 = I8::from(1u8);
```

After:

```sway
let my_i8: I8 = I8::try_from(1u8).unwrap();
```

- [#273](https://github.com/FuelLabs/sway-libs/pull/273) The `neg_from` implementation for all signed integers has been removed. The `neg_try_from()` implementation has been added in its place.

The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types.

Before:

```sway
let my_negative_i8: I8 = I8::neg_from(1u8);
```

After:

```sway
let my_negative_i8: I8 = I8::neg_try_from(1u8).unwrap();
```
78 changes: 42 additions & 36 deletions libs/src/signed_integers/i128.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library;

use std::u128::U128;
use std::{convert::TryFrom, u128::U128};
use ::signed_integers::common::WrappingNeg;
use ::signed_integers::errors::Error;

Expand Down Expand Up @@ -39,15 +39,6 @@ impl I128 {
}
}

impl From<U128> for I128 {
/// Helper function to get a signed number from with an underlying
fn from(value: U128) -> Self {
// as the minimal value of I128 is -I128::indent() (1 << 63) we should add I128::indent() (1 << 63)
let underlying: U128 = value + Self::indent();
Self { underlying }
}
}

impl core::ops::Eq for I128 {
fn eq(self, other: Self) -> bool {
self.underlying == other.underlying
Expand Down Expand Up @@ -167,7 +158,7 @@ impl I128 {
///
/// # Returns
///
/// * [I128] - The newly created `I128` struct.
/// * [Option<I128>] - The newly created `I128` struct.
///
/// # Examples
///
Expand All @@ -177,13 +168,17 @@ impl I128 {
///
/// fn foo() {
/// let underlying = U128::from((1, 0));
/// let i128 = I128::neg_from(underlying);
/// let i128 = I128::neg_try_from(underlying).unwrap();
/// assert(i128.underlying() == U128::from((0, 0)));
/// }
/// ```
pub fn neg_from(value: U128) -> Self {
Self {
underlying: Self::indent() - value,
pub fn neg_try_from(value: U128) -> Option<Self> {
if value <= Self::indent() {
Some(Self {
underlying: Self::indent() - value,
})
} else {
None
}
}

Expand Down Expand Up @@ -377,33 +372,21 @@ impl core::ops::Subtract for I128 {
/// Subtract a I128 from a I128. Panics of overflow.
fn subtract(self, other: Self) -> Self {
let mut res = Self::new();
if (self.underlying > Self::indent()
|| self.underlying == Self::indent())
&& (other.underlying > Self::indent()
|| other.underlying == Self::indent())
{
if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive
if self.underlying > other.underlying {
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else {
res = Self::from_uint(self.underlying - (other.underlying - Self::indent()));
}
} else if (self.underlying > Self::indent()
|| self.underlying == Self::indent())
&& other.underlying < Self::indent()
{
res = Self::from_uint(self.underlying - Self::indent() + other.underlying);
} else if self.underlying < Self::indent()
&& (other.underlying > Self::indent()
|| other.underlying == Self::indent())
{
} else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive
res = Self::from_uint(self.underlying - (other.underlying - Self::indent()));
} else if self.underlying < Self::indent()
&& other.underlying < Self::indent()
{
if self.underlying < other.underlying {
res = Self::from_uint(other.underlying - self.underlying + Self::indent());
} else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative
if self.underlying > other.underlying {
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else {
res = Self::from_uint(self.underlying + other.underlying - Self::indent());
res = Self::from_uint((self.underlying + Self::indent()) - other.underlying);
}
}
res
Expand All @@ -415,6 +398,29 @@ impl WrappingNeg for I128 {
if self == self::min() {
return self::min()
}
self * Self::neg_from(U128::from((0, 1)))
self * Self::neg_try_from(U128::from((0, 1))).unwrap()
}
}

impl TryFrom<U128> for I128 {
fn try_from(value: U128) -> Option<Self> {
// as the minimal value of I128 is -I128::indent() (1 << 63) we should add I128::indent() (1 << 63)
if value < U128::max() - Self::indent() {
Some(Self {
underlying: value + Self::indent(),
})
} else {
None
}
}
}

impl TryFrom<I128> for U128 {
fn try_from(value: I128) -> Option<Self> {
if value >= I128::zero() {
Some(value.underlying - I128::indent())
} else {
None
}
}
}
73 changes: 42 additions & 31 deletions libs/src/signed_integers/i16.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
library;

use std::convert::TryFrom;
use ::signed_integers::errors::Error;
use ::signed_integers::common::WrappingNeg;

Expand Down Expand Up @@ -37,15 +38,6 @@ impl I16 {
}
}

impl From<u16> for I16 {
/// Helper function to get a signed number from with an underlying
fn from(value: u16) -> Self {
// as the minimal value of I16 is -I16::indent() (1 << 15) we should add I16::indent() (1 << 15)
let underlying: u16 = value + Self::indent();
Self { underlying }
}
}

impl core::ops::Eq for I16 {
fn eq(self, other: Self) -> bool {
self.underlying == other.underlying
Expand Down Expand Up @@ -162,7 +154,7 @@ impl I16 {
///
/// # Returns
///
/// * [I16] - The newly created `I16` struct.
/// * [Option<I16>] - The newly created `I16` struct.
///
/// # Examples
///
Expand All @@ -171,13 +163,17 @@ impl I16 {
///
/// fn foo() {
/// let underlying = 1u16;
/// let i16 = I16::neg_from(underlying);
/// let i16 = I16::neg_try_from(underlying).unwrap();
/// assert(i16.underlying() == 32767u16)
/// }
/// ```
pub fn neg_from(value: u16) -> Self {
Self {
underlying: Self::indent() - value,
pub fn neg_try_from(value: u16) -> Option<Self> {
if value <= Self::indent() {
Some(Self {
underlying: Self::indent() - value,
})
} else {
None
}
}

Expand Down Expand Up @@ -364,29 +360,21 @@ impl core::ops::Subtract for I16 {
/// Subtract a I16 from a I16. Panics of overflow.
fn subtract(self, other: Self) -> Self {
let mut res = Self::new();
if self.underlying >= Self::indent()
&& other.underlying >= Self::indent()
{
if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive
if self.underlying > other.underlying {
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else {
res = Self::from_uint(self.underlying - (other.underlying - Self::indent()));
}
} else if self.underlying >= Self::indent()
&& other.underlying < Self::indent()
{
res = Self::from_uint(self.underlying - Self::indent() + other.underlying);
} else if self.underlying < Self::indent()
&& other.underlying >= Self::indent()
{
} else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive
res = Self::from_uint(self.underlying - (other.underlying - Self::indent()));
} else if self.underlying < Self::indent()
&& other.underlying < Self::indent()
{
if self.underlying < other.underlying {
res = Self::from_uint(other.underlying - self.underlying + Self::indent());
} else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative
if self.underlying > other.underlying {
res = Self::from_uint(self.underlying - other.underlying + Self::indent());
} else {
res = Self::from_uint(self.underlying + other.underlying - Self::indent());
res = Self::from_uint((self.underlying + Self::indent()) - other.underlying);
}
}
res
Expand All @@ -398,6 +386,29 @@ impl WrappingNeg for I16 {
if self == self::min() {
return self::min()
}
self * Self::neg_from(1u16)
self * Self::neg_try_from(1u16).unwrap()
}
}

impl TryFrom<u16> for I16 {
fn try_from(value: u16) -> Option<Self> {
// as the minimal value of I16 is -I16::indent() (1 << 15) we should add I16::indent() (1 << 15)
if value < u16::max() - Self::indent() {
Some(Self {
underlying: value + Self::indent(),
})
} else {
None
}
}
}

impl TryFrom<I16> for u16 {
fn try_from(value: I16) -> Option<Self> {
if value >= I16::zero() {
Some(value.underlying - I16::indent())
} else {
None
}
}
}
Loading

0 comments on commit a5f5696

Please sign in to comment.