void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, const void *data, size_t dlen) { if (unsigned_add_overflows(pos, len)) die("you want to use way too much memory"); if (pos > sb->len) die("`pos' is too far after the end of the buffer"); if (pos + len > sb->len) die("`pos + len' is too far after the end of the buffer"); if (dlen >= len) strbuf_grow(sb, dlen - len); memmove(sb->buf + pos + dlen, sb->buf + pos + len, sb->len - pos - len); memcpy(sb->buf + pos, data, dlen); strbuf_setlen(sb, sb->len + dlen - len); }
static time_t gm_time_t(timestamp_t time, int tz) { int minutes; minutes = tz < 0 ? -tz : tz; minutes = (minutes / 100)*60 + (minutes % 100); minutes = tz < 0 ? -minutes : minutes; if (minutes > 0) { if (unsigned_add_overflows(time, minutes * 60)) die("Timestamp+tz too large: %"PRItime" +%04d", time, tz); } else if (time < -minutes * 60) die("Timestamp before Unix epoch: %"PRItime" %04d", time, tz); time += minutes * 60; if (date_overflows(time)) die("Timestamp too large for this system: %"PRItime, time); return (time_t)time; }
void *patch_delta(const void *src_buf, unsigned long src_size, const void *delta_buf, unsigned long delta_size, unsigned long *dst_size) { const unsigned char *data, *top; unsigned char *dst_buf, *out, cmd; unsigned long size; if (delta_size < DELTA_SIZE_MIN) return NULL; data = delta_buf; top = (const unsigned char *) delta_buf + delta_size; /* make sure the orig file size matches what we expect */ size = get_delta_hdr_size(&data, top); if (size != src_size) return NULL; /* now the result size */ size = get_delta_hdr_size(&data, top); dst_buf = xmallocz(size); out = dst_buf; while (data < top) { cmd = *data++; if (cmd & 0x80) { unsigned long cp_off = 0, cp_size = 0; if (cmd & 0x01) cp_off = *data++; if (cmd & 0x02) cp_off |= (*data++ << 8); if (cmd & 0x04) cp_off |= (*data++ << 16); if (cmd & 0x08) cp_off |= ((unsigned) *data++ << 24); if (cmd & 0x10) cp_size = *data++; if (cmd & 0x20) cp_size |= (*data++ << 8); if (cmd & 0x40) cp_size |= (*data++ << 16); if (cp_size == 0) cp_size = 0x10000; if (unsigned_add_overflows(cp_off, cp_size) || cp_off + cp_size > src_size || cp_size > size) break; memcpy(out, (char *) src_buf + cp_off, cp_size); out += cp_size; size -= cp_size; } else if (cmd) { if (cmd > size) break; memcpy(out, data, cmd); out += cmd; data += cmd; size -= cmd; } else { /* * cmd == 0 is reserved for future encoding * extensions. In the mean time we must fail when * encountering them (might be data corruption). */ error("unexpected delta opcode 0"); goto bad; } } /* sanity check */ if (data != top || size != 0) { error("delta replay has gone wild"); bad: free(dst_buf); return NULL; } *dst_size = out - dst_buf; return dst_buf; }