static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) { ut64 len, check_len; int i, j, k, tsize, endian, m = 1; if (!b || b->empty) return 0; if (addr == R_BUF_CUR) addr = b->cur; else addr -= b->base; if (addr == UT64_MAX || addr > b->length) return -1; tsize = 2; for (i = len = 0; i < n; i++) for (j = 0; fmt[j]; j++) { switch (fmt[j]) { case '0'...'9': if (m == 1) m = r_num_get (NULL, &fmt[j]); continue; case 's': tsize = 2; endian = 1; break; case 'S': tsize = 2; endian = 0; break; case 'i': tsize = 4; endian = 1; break; case 'I': tsize = 4; endian = 0; break; case 'l': tsize = 8; endian = 1; break; case 'L': tsize = 8; endian = 0; break; case 'c': tsize = 1; endian = 1; break; default: return -1; } /* Avoid read/write out of bound. tsize and m are not user controled, then don't need to check possible overflow. */ if (!UT64_ADD (&check_len, len, tsize*m)) return -1; if (!UT64_ADD (&check_len, check_len, addr)) return -1; if (check_len > b->length) { return check_len; // return -1; } for (k = 0; k < m; k++) { if (write) { r_mem_copyendian ( (ut8*)&buf[addr+len+(k*tsize)], (ut8*)&b->buf[len+(k*tsize)], tsize, endian); } else { r_mem_copyendian ( (ut8*)&buf[len+(k*tsize)], (ut8*)&b->buf[addr+len+(k*tsize)], tsize, endian); } } len += tsize*m; m = 1; } b->cur = addr + len; return len; }
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) { ut64 len, check_len; int i, j, k, tsize, bigendian, m = 1; if (!b || b->empty) return 0; if (b->fd != -1) { eprintf ("r_buf_fcpy_at not supported yet for r_buf_new_file\n"); return 0; } if (addr == R_BUF_CUR) addr = b->cur; else addr -= b->base; if (addr == UT64_MAX || addr > b->length) return -1; tsize = 2; for (i = len = 0; i < n; i++) for (j = 0; fmt[j]; j++) { switch (fmt[j]) { #ifdef _MSC_VER case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9': #else case '0'...'9': #endif if (m == 1) m = r_num_get (NULL, &fmt[j]); continue; case 's': tsize = 2; bigendian = 0; break; case 'S': tsize = 2; bigendian = 1; break; case 'i': tsize = 4; bigendian = 0; break; case 'I': tsize = 4; bigendian = 1; break; case 'l': tsize = 8; bigendian = 0; break; case 'L': tsize = 8; bigendian = 1; break; case 'c': tsize = 1; bigendian = 0; break; default: return -1; } /* Avoid read/write out of bound. tsize and m are not user controled, then don't need to check possible overflow. */ if (!UT64_ADD (&check_len, len, tsize*m)) return -1; if (!UT64_ADD (&check_len, check_len, addr)) return -1; if (check_len > b->length) { return check_len; // return -1; } for (k = 0; k < m; k++) { ut8* src1 = &b->buf[len+(k*tsize)]; ut8* src2 = &b->buf[addr+len+(k*tsize)]; void* dest1 = &buf[addr+len+(k*tsize)]; void* dest2 = &buf[len+(k*tsize)]; ut8* dest1_8 = (ut8*)dest1; ut16* dest1_16 = (ut16*)dest1; ut32* dest1_32 = (ut32*)dest1; ut64* dest1_64 = (ut64*)dest1; ut8* dest2_8 = (ut8*)dest2; ut16* dest2_16 = (ut16*)dest2; ut32* dest2_32 = (ut32*)dest2; ut64* dest2_64 = (ut64*)dest2; if (write) { switch (tsize) { case 1: *dest1_8 = r_read_ble8 (src1); break; case 2: *dest1_16 = r_read_ble16 (src1, bigendian); break; case 4: *dest1_32 = r_read_ble32 (src1, bigendian); break; case 8: *dest1_64 = r_read_ble64 (src1, bigendian); break; } } else { switch (tsize) { case 1: *dest2_8 = r_read_ble8 (src2); break; case 2: *dest2_16 = r_read_ble16 (src2, bigendian); break; case 4: *dest2_32 = r_read_ble32 (src2, bigendian); break; case 8: *dest2_64 = r_read_ble64 (src2, bigendian); break; } } } len += tsize * m; m = 1; } b->cur = addr + len; return len; }