github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/bytes/boundary_test.gno (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  //
     5  //go:build linux
     6  
     7  package bytes_test
     8  
     9  import (
    10  	"bytes"
    11  	"testing"
    12  )
    13  
    14  // This file tests the situation where byte operations are checking
    15  // data very near to a page boundary. We want to make sure those
    16  // operations do not read across the boundary and cause a page
    17  // fault where they shouldn't.
    18  
    19  // These tests run only on linux. The code being tested is
    20  // not OS-specific, so it does not need to be tested on all
    21  // operating systems.
    22  
    23  /* XXX removed due to syscall.
    24  // dangerousSlice returns a slice which is immediately
    25  // preceded and followed by a faulting page.
    26  func dangerousSlice(t *testing.T) []byte {
    27  	pagesize := syscall.Getpagesize()
    28  	b, err := syscall.Mmap(0, 0, 3*pagesize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANONYMOUS|syscall.MAP_PRIVATE)
    29  	if err != nil {
    30  		t.Fatalf("mmap failed %s", err)
    31  	}
    32  	err = syscall.Mprotect(b[:pagesize], syscall.PROT_NONE)
    33  	if err != nil {
    34  		t.Fatalf("mprotect low failed %s\n", err)
    35  	}
    36  	err = syscall.Mprotect(b[2*pagesize:], syscall.PROT_NONE)
    37  	if err != nil {
    38  		t.Fatalf("mprotect high failed %s\n", err)
    39  	}
    40  	return b[pagesize : 2*pagesize]
    41  }
    42  */
    43  // XXX not dangerous
    44  func dangerousSlice(t *testing.T) []byte {
    45  	return make([]byte, 4096)
    46  }
    47  
    48  func TestEqualNearPageBoundary(t *testing.T) {
    49  	t.Parallel()
    50  	b := dangerousSlice(t)
    51  	for i := range b {
    52  		b[i] = 'A'
    53  	}
    54  	for i := 0; i <= len(b); i++ {
    55  		bytes.Equal(b[:i], b[len(b)-i:])
    56  		bytes.Equal(b[len(b)-i:], b[:i])
    57  	}
    58  }
    59  
    60  func TestIndexByteNearPageBoundary(t *testing.T) {
    61  	t.Parallel()
    62  	b := dangerousSlice(t)
    63  	for i := range b {
    64  		idx := bytes.IndexByte(b[i:], 1)
    65  		if idx != -1 {
    66  			t.Fatalf("IndexByte(b[%d:])=%d, want -1\n", i, idx)
    67  		}
    68  	}
    69  }
    70  
    71  func TestIndexNearPageBoundary(t *testing.T) {
    72  	t.Parallel()
    73  	var q [64]byte
    74  	b := dangerousSlice(t)
    75  	if len(b) > 256 {
    76  		// Only worry about when we're near the end of a page.
    77  		b = b[len(b)-256:]
    78  	}
    79  	for j := 1; j < len(q); j++ {
    80  		q[j-1] = 1 // difference is only found on the last byte
    81  		for i := range b {
    82  			idx := bytes.Index(b[i:], q[:j])
    83  			if idx != -1 {
    84  				t.Fatalf("Index(b[%d:], q[:%d])=%d, want -1\n", i, j, idx)
    85  			}
    86  		}
    87  		q[j-1] = 0
    88  	}
    89  }