@@ -109,17 +109,30 @@ func (dst *Set) Lookup(d string) (digest.Digest, error) {
109109 }
110110 }
111111 idx := sort .Search (len (dst .entries ), searchFunc )
112- if idx == len (dst .entries ) || ! checkShortMatch (dst .entries [idx ].alg , dst .entries [idx ].val , string (alg ), hex ) {
113- return "" , ErrDigestNotFound
114- }
115- if dst .entries [idx ].alg == alg && dst .entries [idx ].val == hex {
116- return dst .entries [idx ].digest , nil
112+
113+ // Entries whose value has hex as a prefix form a contiguous run starting
114+ // at idx. Digests of a different algorithm may sort within that run, so a
115+ // second matching entry is not necessarily adjacent to the first; scan the
116+ // whole run instead of only inspecting idx and idx+1.
117+ var match * digestEntry
118+ for i := idx ; i < len (dst .entries ) && strings .HasPrefix (dst .entries [i ].val , hex ); i ++ {
119+ if ! checkShortMatch (dst .entries [i ].alg , dst .entries [i ].val , string (alg ), hex ) {
120+ continue
121+ }
122+ if dst .entries [i ].alg == alg && dst .entries [i ].val == hex {
123+ // An exact whole-value match is unambiguous.
124+ return dst .entries [i ].digest , nil
125+ }
126+ if match != nil {
127+ return "" , ErrDigestAmbiguous
128+ }
129+ match = dst .entries [i ]
117130 }
118- if idx + 1 < len ( dst . entries ) && checkShortMatch ( dst . entries [ idx + 1 ]. alg , dst . entries [ idx + 1 ]. val , string ( alg ), hex ) {
119- return "" , ErrDigestAmbiguous
131+ if match == nil {
132+ return "" , ErrDigestNotFound
120133 }
121134
122- return dst . entries [ idx ] .digest , nil
135+ return match .digest , nil
123136}
124137
125138// Add adds the given digest to the set. An error will be returned
0 commit comments