(dst *bytes.Buffer, src, delta []byte)
| 249 | } |
| 250 | |
| 251 | func patchDelta(dst *bytes.Buffer, src, delta []byte) error { |
| 252 | srcSz, delta, err := decodeLEB128(delta) |
| 253 | if err != nil { |
| 254 | return fmt.Errorf("%w: %w", ErrInvalidDelta, err) |
| 255 | } |
| 256 | if srcSz != uint(len(src)) { |
| 257 | return ErrInvalidDelta |
| 258 | } |
| 259 | |
| 260 | targetSz, delta, err := decodeLEB128(delta) |
| 261 | if err != nil { |
| 262 | return fmt.Errorf("%w: %w", ErrInvalidDelta, err) |
| 263 | } |
| 264 | remainingTargetSz := targetSz |
| 265 | |
| 266 | growSz := min(targetSz, maxPatchPreemptionSize) |
| 267 | dst.Grow(int(growSz)) |
| 268 | |
| 269 | for remainingTargetSz > 0 { |
| 270 | if len(delta) == 0 { |
| 271 | return ErrInvalidDelta |
| 272 | } |
| 273 | |
| 274 | cmd := delta[0] |
| 275 | delta = delta[1:] |
| 276 | |
| 277 | switch { |
| 278 | case isCopyFromSrc(cmd): |
| 279 | var offset, sz uint |
| 280 | var err error |
| 281 | offset, delta, err = decodeOffset(cmd, delta) |
| 282 | if err != nil { |
| 283 | return err |
| 284 | } |
| 285 | |
| 286 | sz, delta, err = decodeSize(cmd, delta) |
| 287 | if err != nil { |
| 288 | return err |
| 289 | } |
| 290 | |
| 291 | if invalidSize(sz, remainingTargetSz) || |
| 292 | invalidOffsetSize(offset, sz, srcSz) { |
| 293 | return ErrInvalidDelta |
| 294 | } |
| 295 | dst.Write(src[offset : offset+sz]) |
| 296 | remainingTargetSz -= sz |
| 297 | |
| 298 | case isCopyFromDelta(cmd): |
| 299 | sz := uint(cmd) // cmd is the size itself |
| 300 | if invalidSize(sz, remainingTargetSz) { |
| 301 | return ErrInvalidDelta |
| 302 | } |
| 303 | |
| 304 | if uint(len(delta)) < sz { |
| 305 | return ErrInvalidDelta |
| 306 | } |
| 307 | |
| 308 | dst.Write(delta[0:sz]) |
searching dependent graphs…