Browse Source

Fuzz Base64 and Base64URL (#4853)

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Ernesto García 1 year ago
parent
commit
6b30d2d8de
4 changed files with 20 additions and 49 deletions
  1. 1 2
      .github/workflows/checks.yml
  2. 1 1
      lib/forge-std
  3. 0 31
      scripts/tests/base64.sh
  4. 18 15
      test/utils/Base64.t.sol

+ 1 - 2
.github/workflows/checks.yml

@@ -83,8 +83,7 @@ jobs:
       - name: Set up environment
         uses: ./.github/actions/setup
       - name: Run tests
-        # Base64Test requires `--ffi`. See test/utils/Base64.t.sol
-        run: forge test -vv --no-match-contract Base64Test
+        run: forge test -vv
 
   coverage:
     runs-on: ubuntu-latest

+ 1 - 1
lib/forge-std

@@ -1 +1 @@
-Subproject commit c2236853aadb8e2d9909bbecdc490099519b70a4
+Subproject commit ae570fec082bfe1c1f45b0acca4a2b4f84d345ce

+ 0 - 31
scripts/tests/base64.sh

@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-_encode() {
-  # - Print the input to stdout
-  # - Remove the first two characters
-  # - Convert from hex to binary
-  # - Convert from binary to base64
-  # - Remove newlines from `base64` output
-  echo -n "$1" | cut -c 3- | xxd -r -p | base64 | tr -d \\n
-}
-
-encode() {
-  # - Convert from base64 to hex
-  # - Remove newlines from `xxd` output
-  _encode "$1" | xxd -p | tr -d \\n
-}
-
-encodeURL() {
-  # - Remove padding from `base64` output
-  # - Replace `+` with `-`
-  # - Replace `/` with `_`
-  # - Convert from base64 to hex
-  # - Remove newlines from `xxd` output
-  _encode "$1" | sed 's/=//g' | sed 's/+/-/g' | sed 's/\//_/g' | xxd -p | tr -d \\n
-}
-
-# $1: function name
-# $2: input
-$1 $2

+ 18 - 15
test/utils/Base64.t.sol

@@ -6,27 +6,30 @@ import {Test} from "forge-std/Test.sol";
 
 import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
 
-/// NOTE: This test requires `ffi` to be enabled. It does not run in the CI
-/// environment given `ffi` is not recommended.
-/// See: https://github.com/foundry-rs/foundry/issues/6744
 contract Base64Test is Test {
     function testEncode(bytes memory input) external {
-        string memory output = Base64.encode(input);
-        assertEq(output, _base64Ffi(input, "encode"));
+        assertEq(Base64.encode(input), vm.toBase64(input));
     }
 
     function testEncodeURL(bytes memory input) external {
-        string memory output = Base64.encodeURL(input);
-        assertEq(output, _base64Ffi(input, "encodeURL"));
+        assertEq(Base64.encodeURL(input), _removePadding(vm.toBase64URL(input)));
     }
 
-    function _base64Ffi(bytes memory input, string memory fn) internal returns (string memory) {
-        string[] memory command = new string[](4);
-        command[0] = "bash";
-        command[1] = "scripts/tests/base64.sh";
-        command[2] = fn;
-        command[3] = vm.toString(input);
-        bytes memory retData = vm.ffi(command);
-        return string(retData);
+    function _removePadding(string memory inputStr) internal pure returns (string memory) {
+        bytes memory input = bytes(inputStr);
+        bytes memory output;
+
+        for (uint256 i = 0; i < input.length; ++i) {
+            if (input[input.length - i - 1] != 0x3d) {
+                output = new bytes(input.length - i);
+                break;
+            }
+        }
+
+        for (uint256 i = 0; i < output.length; ++i) {
+            output[i] = input[i];
+        }
+
+        return string(output);
     }
 }