[svg] Reference cycle avoidance

Several SVG constructs reference other elements based on their ID (e.g.
<use>).  This can yield arbitrary reference chains and cycles.

Since all ID-based lookups are funneled through
SkSVGRenderContext::findNodeById(), a straightforward method to break
cycles is to temporarily clear the id->node association following a
lookup -- where "temporarily" refers to the local execution scope.

This approach works for all recursive traversals, as scopes are
nested/released in a natural manner.

  - introduce a scoped node reference wrapper (BorrowedNode), which
    clears the id mapping for its lifetime and restores it upon
    destruction
  - update findNodeById() return BorrowedNode values
  - update call sites as needed

Change-Id: I2ec5539b24e23b4fbbaff01a44460c41190028e0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282271
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
5 files changed