[The same bug exists in `with-output-to-string']
A short test case shows the problem.
(let (a1 a2)
(with-string-as-buffer-contents "foo"
(setq a1 (buffer-substring (point-min) (point-max)))
(with-string-as-buffer-contents "bar"
(setq a2 (buffer-substring (point-min) (point-max))))
(message "a2 = `%s', a1 = `%s', buffer = `%s'"
a2 a1 (buffer-substring (point-min) (point-max)))))
I see output:
a2 = `bar', a1 = `foo', buffer = `'
The problem in both functions is that `get-buffer-create' is called
with a constant string. Recursive invocations reuse existing buffers
and when the recursive call finishes, the outer form's buffer is
trashed.