return: * 0 - succes * 1 - succes, null value in db * 2 - error * 3 - does not match reload version (old value) */
| 1520 | * 3 - does not match reload version (old value) |
| 1521 | */ |
| 1522 | static int cdb_val_decode(const pv_name_fix_t *pv_name, const str *cdb_val, int reload_version, |
| 1523 | str *str_res, int *int_res) |
| 1524 | { |
| 1525 | int int_val, next_str_off, i, rc; |
| 1526 | char int_buf[calc_max_base64_decode_len(INT_B64_ENC_LEN)]; |
| 1527 | const char zeroes[INT_B64_ENC_LEN] = {0}; |
| 1528 | |
| 1529 | if (pv_name->col_offset == -1) { |
| 1530 | LM_WARN("Unknown column %.*s\n", pv_name->col.len, pv_name->col.s); |
| 1531 | return 2; |
| 1532 | } |
| 1533 | |
| 1534 | /* decode the reload version */ |
| 1535 | if (base64decode((unsigned char *)int_buf, |
| 1536 | (unsigned char *)(cdb_val->s), INT_B64_ENC_LEN) != 4) |
| 1537 | goto error; |
| 1538 | memcpy(&int_val, int_buf, 4); |
| 1539 | |
| 1540 | if (reload_version != int_val) |
| 1541 | return 3; |
| 1542 | |
| 1543 | /* null integer value in db */ |
| 1544 | if (!memcmp(cdb_val->s + pv_name->col_offset, zeroes, INT_B64_ENC_LEN)) |
| 1545 | return 1; |
| 1546 | |
| 1547 | /* decode the integer value or the offset of the string value */ |
| 1548 | if (base64decode((unsigned char *)int_buf, |
| 1549 | (unsigned char *)(cdb_val->s + pv_name->col_offset), INT_B64_ENC_LEN) != 4) |
| 1550 | goto error; |
| 1551 | memcpy(&int_val, int_buf, 4); |
| 1552 | |
| 1553 | if (is_str_column(pv_name)) { |
| 1554 | /* null string value in db */ |
| 1555 | if (int_val == 0) |
| 1556 | return 1; |
| 1557 | |
| 1558 | str_res->s = cdb_val->s + int_val; |
| 1559 | if (pv_name->last_str) |
| 1560 | str_res->len = cdb_val->len - int_val; |
| 1561 | else { |
| 1562 | /* calculate the length of the current string using the offset of the next not null string */ |
| 1563 | i = 1; |
| 1564 | do { |
| 1565 | rc = base64decode((unsigned char *)int_buf, (unsigned char *)(cdb_val->s + |
| 1566 | pv_name->col_offset + i * INT_B64_ENC_LEN), INT_B64_ENC_LEN); |
| 1567 | if (rc != 4) |
| 1568 | goto error; |
| 1569 | memcpy(&next_str_off, int_buf, 4); |
| 1570 | i++; |
| 1571 | } while (next_str_off == 0 && pv_name->col_offset + i*INT_B64_ENC_LEN < |
| 1572 | (pv_name->c_entry->nr_columns + 1) * INT_B64_ENC_LEN); |
| 1573 | |
| 1574 | if (next_str_off == 0) |
| 1575 | str_res->len = cdb_val->len - int_val; |
| 1576 | else |
| 1577 | str_res->len = next_str_off - int_val; |
| 1578 | } |
| 1579 | } else { |
no test coverage detected