(length uint8)
| 61 | var randStringScratchPool = sync.Pool{New: func() any { return new(randStringScratch) }} |
| 62 | |
| 63 | func randomString(length uint8) string { |
| 64 | reader := randomReaderPool.Get().(*bufio.Reader) |
| 65 | defer randomReaderPool.Put(reader) |
| 66 | sc := randStringScratchPool.Get().(*randStringScratch) |
| 67 | defer randStringScratchPool.Put(sc) |
| 68 | |
| 69 | n := int(length) |
| 70 | if cap(sc.b) < n { |
| 71 | sc.b = make([]byte, n) |
| 72 | } else { |
| 73 | sc.b = sc.b[:n] |
| 74 | } |
| 75 | rlen := n + n/4 // perf: avoid read from rand.Reader many times |
| 76 | if cap(sc.r) < rlen { |
| 77 | sc.r = make([]byte, rlen) |
| 78 | } else { |
| 79 | sc.r = sc.r[:rlen] |
| 80 | } |
| 81 | b, r := sc.b, sc.r |
| 82 | var i uint8 = 0 |
| 83 | |
| 84 | // security note: |
| 85 | // we can't just simply do b[i]=randomStringCharset[rb%len(randomStringCharset)], |
| 86 | // len(len(randomStringCharset)) is 52, and rb is [0, 255], 256 = 52 * 4 + 48. |
| 87 | // make the first 48 characters more possibly to be generated then others. |
| 88 | // So we have to skip bytes when rb > randomStringMaxByt |
| 89 | |
| 90 | for { |
| 91 | _, err := io.ReadFull(reader, r) |
| 92 | if err != nil { |
| 93 | panic("unexpected error happened when reading from bufio.NewReader(crypto/rand.Reader)") |
| 94 | } |
| 95 | for _, rb := range r { |
| 96 | if rb > randomStringMaxByte { |
| 97 | // Skip this number to avoid bias. |
| 98 | continue |
| 99 | } |
| 100 | b[i] = randomStringCharset[rb%randomStringCharsetLen] |
| 101 | i++ |
| 102 | if i == length { |
| 103 | return string(b[:length]) |
| 104 | } |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | func validateOrigins(origins []string, what string) error { |
| 110 | for _, o := range origins { |
searching dependent graphs…