Эх сурвалжийг харах

Protect Packing.pack and Packing.replace against values that include dirty bits (#5117)

Hadrien Croubois 1 жил өмнө
parent
commit
19a657bef8

+ 125 - 0
contracts/utils/Packing.sol

@@ -35,210 +35,280 @@ library Packing {
 
     function pack_1_1(bytes1 left, bytes1 right) internal pure returns (bytes2 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(248, not(0)))
+            right := and(right, shl(248, not(0)))
             result := or(left, shr(8, right))
         }
     }
 
     function pack_2_2(bytes2 left, bytes2 right) internal pure returns (bytes4 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(240, not(0)))
+            right := and(right, shl(240, not(0)))
             result := or(left, shr(16, right))
         }
     }
 
     function pack_2_4(bytes2 left, bytes4 right) internal pure returns (bytes6 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(240, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(16, right))
         }
     }
 
     function pack_2_6(bytes2 left, bytes6 right) internal pure returns (bytes8 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(240, not(0)))
+            right := and(right, shl(208, not(0)))
             result := or(left, shr(16, right))
         }
     }
 
     function pack_4_2(bytes4 left, bytes2 right) internal pure returns (bytes6 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(240, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_4(bytes4 left, bytes4 right) internal pure returns (bytes8 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_8(bytes4 left, bytes8 right) internal pure returns (bytes12 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_12(bytes4 left, bytes12 right) internal pure returns (bytes16 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(160, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_16(bytes4 left, bytes16 right) internal pure returns (bytes20 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(128, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_20(bytes4 left, bytes20 right) internal pure returns (bytes24 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(96, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_24(bytes4 left, bytes24 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(64, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_4_28(bytes4 left, bytes28 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(224, not(0)))
+            right := and(right, shl(32, not(0)))
             result := or(left, shr(32, right))
         }
     }
 
     function pack_6_2(bytes6 left, bytes2 right) internal pure returns (bytes8 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(208, not(0)))
+            right := and(right, shl(240, not(0)))
             result := or(left, shr(48, right))
         }
     }
 
     function pack_6_6(bytes6 left, bytes6 right) internal pure returns (bytes12 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(208, not(0)))
+            right := and(right, shl(208, not(0)))
             result := or(left, shr(48, right))
         }
     }
 
     function pack_8_4(bytes8 left, bytes4 right) internal pure returns (bytes12 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_8_8(bytes8 left, bytes8 right) internal pure returns (bytes16 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_8_12(bytes8 left, bytes12 right) internal pure returns (bytes20 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(160, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_8_16(bytes8 left, bytes16 right) internal pure returns (bytes24 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(128, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_8_20(bytes8 left, bytes20 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(96, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_8_24(bytes8 left, bytes24 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(192, not(0)))
+            right := and(right, shl(64, not(0)))
             result := or(left, shr(64, right))
         }
     }
 
     function pack_12_4(bytes12 left, bytes4 right) internal pure returns (bytes16 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(160, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(96, right))
         }
     }
 
     function pack_12_8(bytes12 left, bytes8 right) internal pure returns (bytes20 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(160, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(96, right))
         }
     }
 
     function pack_12_12(bytes12 left, bytes12 right) internal pure returns (bytes24 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(160, not(0)))
+            right := and(right, shl(160, not(0)))
             result := or(left, shr(96, right))
         }
     }
 
     function pack_12_16(bytes12 left, bytes16 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(160, not(0)))
+            right := and(right, shl(128, not(0)))
             result := or(left, shr(96, right))
         }
     }
 
     function pack_12_20(bytes12 left, bytes20 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(160, not(0)))
+            right := and(right, shl(96, not(0)))
             result := or(left, shr(96, right))
         }
     }
 
     function pack_16_4(bytes16 left, bytes4 right) internal pure returns (bytes20 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(128, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(128, right))
         }
     }
 
     function pack_16_8(bytes16 left, bytes8 right) internal pure returns (bytes24 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(128, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(128, right))
         }
     }
 
     function pack_16_12(bytes16 left, bytes12 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(128, not(0)))
+            right := and(right, shl(160, not(0)))
             result := or(left, shr(128, right))
         }
     }
 
     function pack_16_16(bytes16 left, bytes16 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(128, not(0)))
+            right := and(right, shl(128, not(0)))
             result := or(left, shr(128, right))
         }
     }
 
     function pack_20_4(bytes20 left, bytes4 right) internal pure returns (bytes24 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(96, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(160, right))
         }
     }
 
     function pack_20_8(bytes20 left, bytes8 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(96, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(160, right))
         }
     }
 
     function pack_20_12(bytes20 left, bytes12 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(96, not(0)))
+            right := and(right, shl(160, not(0)))
             result := or(left, shr(160, right))
         }
     }
 
     function pack_24_4(bytes24 left, bytes4 right) internal pure returns (bytes28 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(64, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(192, right))
         }
     }
 
     function pack_24_8(bytes24 left, bytes8 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(64, not(0)))
+            right := and(right, shl(192, not(0)))
             result := or(left, shr(192, right))
         }
     }
 
     function pack_28_4(bytes28 left, bytes4 right) internal pure returns (bytes32 result) {
         assembly ("memory-safe") {
+            left := and(left, shl(32, not(0)))
+            right := and(right, shl(224, not(0)))
             result := or(left, shr(224, right))
         }
     }
@@ -253,6 +323,7 @@ library Packing {
     function replace_2_1(bytes2 self, bytes1 value, uint8 offset) internal pure returns (bytes2 result) {
         bytes1 oldValue = extract_2_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -267,6 +338,7 @@ library Packing {
     function replace_4_1(bytes4 self, bytes1 value, uint8 offset) internal pure returns (bytes4 result) {
         bytes1 oldValue = extract_4_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -281,6 +353,7 @@ library Packing {
     function replace_4_2(bytes4 self, bytes2 value, uint8 offset) internal pure returns (bytes4 result) {
         bytes2 oldValue = extract_4_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -295,6 +368,7 @@ library Packing {
     function replace_6_1(bytes6 self, bytes1 value, uint8 offset) internal pure returns (bytes6 result) {
         bytes1 oldValue = extract_6_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -309,6 +383,7 @@ library Packing {
     function replace_6_2(bytes6 self, bytes2 value, uint8 offset) internal pure returns (bytes6 result) {
         bytes2 oldValue = extract_6_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -323,6 +398,7 @@ library Packing {
     function replace_6_4(bytes6 self, bytes4 value, uint8 offset) internal pure returns (bytes6 result) {
         bytes4 oldValue = extract_6_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -337,6 +413,7 @@ library Packing {
     function replace_8_1(bytes8 self, bytes1 value, uint8 offset) internal pure returns (bytes8 result) {
         bytes1 oldValue = extract_8_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -351,6 +428,7 @@ library Packing {
     function replace_8_2(bytes8 self, bytes2 value, uint8 offset) internal pure returns (bytes8 result) {
         bytes2 oldValue = extract_8_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -365,6 +443,7 @@ library Packing {
     function replace_8_4(bytes8 self, bytes4 value, uint8 offset) internal pure returns (bytes8 result) {
         bytes4 oldValue = extract_8_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -379,6 +458,7 @@ library Packing {
     function replace_8_6(bytes8 self, bytes6 value, uint8 offset) internal pure returns (bytes8 result) {
         bytes6 oldValue = extract_8_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -393,6 +473,7 @@ library Packing {
     function replace_12_1(bytes12 self, bytes1 value, uint8 offset) internal pure returns (bytes12 result) {
         bytes1 oldValue = extract_12_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -407,6 +488,7 @@ library Packing {
     function replace_12_2(bytes12 self, bytes2 value, uint8 offset) internal pure returns (bytes12 result) {
         bytes2 oldValue = extract_12_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -421,6 +503,7 @@ library Packing {
     function replace_12_4(bytes12 self, bytes4 value, uint8 offset) internal pure returns (bytes12 result) {
         bytes4 oldValue = extract_12_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -435,6 +518,7 @@ library Packing {
     function replace_12_6(bytes12 self, bytes6 value, uint8 offset) internal pure returns (bytes12 result) {
         bytes6 oldValue = extract_12_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -449,6 +533,7 @@ library Packing {
     function replace_12_8(bytes12 self, bytes8 value, uint8 offset) internal pure returns (bytes12 result) {
         bytes8 oldValue = extract_12_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -463,6 +548,7 @@ library Packing {
     function replace_16_1(bytes16 self, bytes1 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes1 oldValue = extract_16_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -477,6 +563,7 @@ library Packing {
     function replace_16_2(bytes16 self, bytes2 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes2 oldValue = extract_16_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -491,6 +578,7 @@ library Packing {
     function replace_16_4(bytes16 self, bytes4 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes4 oldValue = extract_16_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -505,6 +593,7 @@ library Packing {
     function replace_16_6(bytes16 self, bytes6 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes6 oldValue = extract_16_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -519,6 +608,7 @@ library Packing {
     function replace_16_8(bytes16 self, bytes8 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes8 oldValue = extract_16_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -533,6 +623,7 @@ library Packing {
     function replace_16_12(bytes16 self, bytes12 value, uint8 offset) internal pure returns (bytes16 result) {
         bytes12 oldValue = extract_16_12(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(160, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -547,6 +638,7 @@ library Packing {
     function replace_20_1(bytes20 self, bytes1 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes1 oldValue = extract_20_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -561,6 +653,7 @@ library Packing {
     function replace_20_2(bytes20 self, bytes2 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes2 oldValue = extract_20_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -575,6 +668,7 @@ library Packing {
     function replace_20_4(bytes20 self, bytes4 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes4 oldValue = extract_20_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -589,6 +683,7 @@ library Packing {
     function replace_20_6(bytes20 self, bytes6 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes6 oldValue = extract_20_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -603,6 +698,7 @@ library Packing {
     function replace_20_8(bytes20 self, bytes8 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes8 oldValue = extract_20_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -617,6 +713,7 @@ library Packing {
     function replace_20_12(bytes20 self, bytes12 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes12 oldValue = extract_20_12(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(160, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -631,6 +728,7 @@ library Packing {
     function replace_20_16(bytes20 self, bytes16 value, uint8 offset) internal pure returns (bytes20 result) {
         bytes16 oldValue = extract_20_16(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(128, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -645,6 +743,7 @@ library Packing {
     function replace_24_1(bytes24 self, bytes1 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes1 oldValue = extract_24_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -659,6 +758,7 @@ library Packing {
     function replace_24_2(bytes24 self, bytes2 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes2 oldValue = extract_24_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -673,6 +773,7 @@ library Packing {
     function replace_24_4(bytes24 self, bytes4 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes4 oldValue = extract_24_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -687,6 +788,7 @@ library Packing {
     function replace_24_6(bytes24 self, bytes6 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes6 oldValue = extract_24_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -701,6 +803,7 @@ library Packing {
     function replace_24_8(bytes24 self, bytes8 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes8 oldValue = extract_24_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -715,6 +818,7 @@ library Packing {
     function replace_24_12(bytes24 self, bytes12 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes12 oldValue = extract_24_12(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(160, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -729,6 +833,7 @@ library Packing {
     function replace_24_16(bytes24 self, bytes16 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes16 oldValue = extract_24_16(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(128, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -743,6 +848,7 @@ library Packing {
     function replace_24_20(bytes24 self, bytes20 value, uint8 offset) internal pure returns (bytes24 result) {
         bytes20 oldValue = extract_24_20(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(96, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -757,6 +863,7 @@ library Packing {
     function replace_28_1(bytes28 self, bytes1 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes1 oldValue = extract_28_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -771,6 +878,7 @@ library Packing {
     function replace_28_2(bytes28 self, bytes2 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes2 oldValue = extract_28_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -785,6 +893,7 @@ library Packing {
     function replace_28_4(bytes28 self, bytes4 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes4 oldValue = extract_28_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -799,6 +908,7 @@ library Packing {
     function replace_28_6(bytes28 self, bytes6 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes6 oldValue = extract_28_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -813,6 +923,7 @@ library Packing {
     function replace_28_8(bytes28 self, bytes8 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes8 oldValue = extract_28_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -827,6 +938,7 @@ library Packing {
     function replace_28_12(bytes28 self, bytes12 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes12 oldValue = extract_28_12(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(160, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -841,6 +953,7 @@ library Packing {
     function replace_28_16(bytes28 self, bytes16 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes16 oldValue = extract_28_16(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(128, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -855,6 +968,7 @@ library Packing {
     function replace_28_20(bytes28 self, bytes20 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes20 oldValue = extract_28_20(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(96, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -869,6 +983,7 @@ library Packing {
     function replace_28_24(bytes28 self, bytes24 value, uint8 offset) internal pure returns (bytes28 result) {
         bytes24 oldValue = extract_28_24(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(64, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -883,6 +998,7 @@ library Packing {
     function replace_32_1(bytes32 self, bytes1 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes1 oldValue = extract_32_1(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(248, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -897,6 +1013,7 @@ library Packing {
     function replace_32_2(bytes32 self, bytes2 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes2 oldValue = extract_32_2(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(240, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -911,6 +1028,7 @@ library Packing {
     function replace_32_4(bytes32 self, bytes4 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes4 oldValue = extract_32_4(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(224, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -925,6 +1043,7 @@ library Packing {
     function replace_32_6(bytes32 self, bytes6 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes6 oldValue = extract_32_6(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(208, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -939,6 +1058,7 @@ library Packing {
     function replace_32_8(bytes32 self, bytes8 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes8 oldValue = extract_32_8(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(192, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -953,6 +1073,7 @@ library Packing {
     function replace_32_12(bytes32 self, bytes12 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes12 oldValue = extract_32_12(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(160, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -967,6 +1088,7 @@ library Packing {
     function replace_32_16(bytes32 self, bytes16 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes16 oldValue = extract_32_16(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(128, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -981,6 +1103,7 @@ library Packing {
     function replace_32_20(bytes32 self, bytes20 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes20 oldValue = extract_32_20(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(96, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -995,6 +1118,7 @@ library Packing {
     function replace_32_24(bytes32 self, bytes24 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes24 oldValue = extract_32_24(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(64, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }
@@ -1009,6 +1133,7 @@ library Packing {
     function replace_32_28(bytes32 self, bytes28 value, uint8 offset) internal pure returns (bytes32 result) {
         bytes28 oldValue = extract_32_28(self, offset);
         assembly ("memory-safe") {
+            value := and(value, shl(32, not(0)))
             result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
         }
     }

+ 3 - 0
scripts/generate/templates/Packing.js

@@ -44,6 +44,8 @@ function pack_${left}_${right}(bytes${left} left, bytes${right} right) internal
   left + right
 } result) {
     assembly ("memory-safe") {
+        left := and(left, shl(${256 - 8 * left}, not(0)))
+        right := and(right, shl(${256 - 8 * right}, not(0)))
         result := or(left, shr(${8 * left}, right))
     }
 }
@@ -62,6 +64,7 @@ const replace = (outer, inner) => `\
 function replace_${outer}_${inner}(bytes${outer} self, bytes${inner} value, uint8 offset) internal pure returns (bytes${outer} result) {
     bytes${inner} oldValue = extract_${outer}_${inner}(self, offset);
     assembly ("memory-safe") {
+        value := and(value, shl(${256 - 8 * inner}, not(0)))
         result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
     }
 }