Day 25: Minimizing bytes for go fuzz
🪵 🍫🔥 Mood: Ready for some s’mores 😋
🎵 Soundtrack: No Lyrics - Folk
📚 Reading Github Issues
Caught up on the 36 github issues opened in the last 3 days.
- One was about inefficient assembly code. This is exactly the reason that I started down my side quest of learning about compilers and assembly. Now I can read the assembly in the issue! Why/how someone noticed that the generated assembly code could be made more efficient by one command is still lost on me though.
- This one also caught my eye. Suspicious.
📌 IP Testable Examples Update
Opening up an issue for my old contribution for IP testable examples seems to have done the trick. The reviewers got back to me with some suggestions, I changed my code, they approved, and it should be merged any time now. Yay! This will be my 5th contribution!
At the onset of this sabbatical I had the idea to try to write testable examples for everything in the net package as a way to learn the net package better. I still like that idea and may continue to do it small bits at a time.
🧶 Make Go Fuzz Crashers Human Readable
Last Thursday afternoon Jay got back to me about my contribution to the go fuzz minimizer to make the crashers more human readable. Initially I was only simplifying strings and was ignoring byte slices. He suggested that I simplify byte slices in the same way. This is great because now I just need to extend one function and the code stays way cleaner. Jay also graciously pointed out an error I made about assuming that each character is 1 byte. 😖 How embarrassingly English-centric of me.
I spent most of this morning diving deeper into ASCII vs UTF-8 vs UNICODE and making sure I wrote my code properly this time. I wrote a test to cover non-ASCII characters.
Then I thought, hey, this is the perfect time for fuzzing! So I wrote a fuzz test for my minimizing function for the go fuzzer! I wrote an approximate version of the function to test with so that I didn’t need the whole fuzzing infrastructure. I let it run for an hour and nothing failed (except my computer trying to run other things). Nice!
package length
import (
"testing"
)
func Simplify(v []byte) {
for i, b := range v {
candidate := make([]byte, len(v))
copy(candidate, v)
// Try to replace every byte with '0'.
candidate[i] = '0'
if try(candidate) {
v = candidate
continue
}
// If '0' doesn't work, then try to replace each byte with a printable,
// single byte character depending on the original byte's value.
switch {
case b < 32 || b >= 127: // Control chars and non-ASCII chars
candidate[i] = '?'
case b >= 65 && b <= 90: // Uppercase latin letters A-Z
candidate[i] = 'A'
case b >= 97 && b <= 122: // Lowercase latin letters a-z
candidate[i] = 'a'
default: // ASCII punctuation and symbols
candidate[i] = '.'
}
if !try(candidate) {
continue
}
// Set v to the new value and continue iterating.
v = candidate
}
}
// try is determanistic. the contents really don't matter.
func try(candidate []byte) bool {
if len(candidate) > 0 && candidate[0] > 100 {
return true
}
return false
}
func FuzzSimplify(f *testing.F) {
f.Add([]byte("AMELIA"))
f.Fuzz(func(t *testing.T, b []byte) {
Simplify(b)
})
}
🎥 Lecture 4: Assembly Language & Computer Architecture
At the end of my day I continued watching (but did not yet finish) this MIT lecture on “Assembly Language & Computer Architecture” that my internet friend recommended.
In this section he covered some assembly idioms:
xor %rax, %rax
- this zeros out the%rax
register by doing anXOR
with itself. This is how my internet friend showed me to zero things out too. Apparently this is faster than having a 0 constant that you move to the register.-
test %rcx, %rcx je DO_SOMETHING
test
does a bitwise AND of its two arguments. Then the jump equal (je
) checks the zero flag. The only way a bitwise AND of a register against itself is going to be zero is if the register is already zero. So this is an idiomatic way to check if%rcx
is zero and if so, then DO_SOMETHING.
🧩 Assembly!
My internet friend challenged me to look up the “AND - Logical
AND”
instruction and see if I could improve my isOddWithNoDiv
function from Day
24.
I didn’t have time today, but I haven’t forgotten kind stranger!