You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
A constant reference is never its own predecessor (#254)
The prefix walk steps back over the segments written before a leaf on its
line, so that Foo::VERSION reports VERSION as the dependency and Foo as the
path it was named through. It finds the previous segment by comparing a
candidate's end column plus the separator against the current segment's start
column, and compares columns alone.
A reference spanning several lines carries an end column belonging to its last
line. When that number plus two happens to equal its own start column, the
reference is returned as its own predecessor, and the walk cannot terminate:
it prepends a name into a freshly allocated slice and goes round again. One
reference does it on a Rails monolith, `<LibDDWAF>` at lib_ddwaf.rb:262, which
spans to line 267 with end column 25 against start column 27. The provider
was killed at 26 minutes holding 6.7GB with nothing written, on a tree the
engine itself indexes in 24 seconds. A second Rails application hung the same
way, so this is not one unlucky vendored gem.
A candidate now qualifies only when it is a different reference and its end
line is the line the walk is on, which are the conditions the adjacency pass
twenty lines earlier already asserts. Adjacency is a property of one line, and
comparing an end column from another line to a start column compares two
unrelated coordinates.
Two things ride along in the same loop. The walk appends and reverses once
instead of prepending into a new slice at every step, and a declaration's name
is fetched across the library boundary once rather than per reference: that
monolith resolves 1,624,360 references to 132,603 declarations, so the same
name was marshalled a dozen times on average.
The regression test builds the reference shape rather than depending on a
workspace, and fails against the previous code by never returning within its
deadline. Facts are byte-for-byte identical on a repository where both builds
complete.