/* Forward declarations */
static int sl_pack_loop(DALLOC_CTX *query, char *buf, int offset, char *toc_buf, int *toc_idx);
+static int sl_unpack_loop(DALLOC_CTX *query, const char *buf, int offset, uint count, const uint toc_offset, const uint encoding);
/*
* Returns the UTF-16 string encoding, by checking the 2-byte byte order mark.
{
int len = 0, off = 0;
int cnid_count = talloc_array_length(cnids->ca_cnids);
+ uint64_t id;
- SLVAL(toc_buf, *toc_idx * 8, sl_pack_tag(SQ_CPX_TYPE_CNIDS, (offset + SL_OFFSET_DELTA) / 8, cnid_count));
+ SLVAL(toc_buf, *toc_idx * 8, sl_pack_tag(SQ_CPX_TYPE_CNIDS, (offset + SL_OFFSET_DELTA) / 8, 0 /* cnid_count */));
SLVAL(buf, offset, sl_pack_tag(SQ_TYPE_COMPLEX, 1, *toc_idx + 1));
*toc_idx += 1;
offset += 8;
offset += 8;
for (int i = 0; i < cnid_count; i++) {
- SLVAL(buf, offset, cnids->ca_cnids->dd_talloc_array[i]);
+ memcpy(&id, cnids->ca_cnids->dd_talloc_array[i], sizeof(uint64_t));
+ SLVAL(buf, offset, id);
offset += 8;
}
}
int count = talloc_array_length(array->dd_talloc_array);
int octets = (offset + SL_OFFSET_DELTA) / 8;
- LOG(log_maxdebug, logtype_sl, "sl_pack_array: count: %d, offset:%d, octets: %d", count, offset, octets);
-
SLVAL(toc_buf, *toc_idx * 8, sl_pack_tag(SQ_CPX_TYPE_ARRAY, octets, count));
SLVAL(buf, offset, sl_pack_tag(SQ_TYPE_COMPLEX, 1, *toc_idx + 1));
*toc_idx += 1;
return offset;
}
-static int sl_pack_string(char **string, char *buf, int offset, char *toc_buf, int *toc_idx)
+static int sl_pack_filemeta(sl_filemeta_t *fm, char *buf, int offset, char *toc_buf, int *toc_idx)
+{
+ int fmlen; /* lenght of filemeta */
+ int saveoff = offset;
+
+ SLVAL(buf, offset, sl_pack_tag(SQ_TYPE_COMPLEX, 1, *toc_idx + 1));
+ offset += 16;
+
+ fmlen = sl_pack(fm, buf + offset);
+ offset += fmlen;
+
+ SLVAL(buf, saveoff + 8, sl_pack_tag(SQ_TYPE_DATA, (fmlen / 8) + 1, 8 /* unknown meaning, but always 8 */));
+
+ SLVAL(toc_buf, *toc_idx * 8, sl_pack_tag(SQ_CPX_TYPE_FILEMETA, (saveoff + SL_OFFSET_DELTA) / 8, fmlen / 8));
+ *toc_idx += 1;
+
+ return offset;
+}
+
+static int sl_pack_string(char *s, char *buf, int offset, char *toc_buf, int *toc_idx)
{
int len, octets, used_in_last_octet;
- char *s = *string;
len = strlen(s);
octets = (len / 8) + (len & 7 ? 1 : 0);
used_in_last_octet = 8 - (octets * 8 - len);
- LOG(log_maxdebug, logtype_sl, "sl_pack_string(\"%s\"): len: %d, octets: %d, used_in_last_octet: %d",
- s, len, octets, used_in_last_octet);
-
SLVAL(toc_buf, *toc_idx * 8, sl_pack_tag(SQ_CPX_TYPE_STRING, (offset + SL_OFFSET_DELTA) / 8, used_in_last_octet));
SLVAL(buf, offset, sl_pack_tag(SQ_TYPE_COMPLEX, 1, *toc_idx + 1));
*toc_idx += 1;
offset = sl_pack_array(query->dd_talloc_array[n], buf, offset, toc_buf, toc_idx);
} else if (STRCMP(type, ==, "sl_dict_t")) {
offset = sl_pack_dict(query->dd_talloc_array[n], buf, offset, toc_buf, toc_idx);
+ } else if (STRCMP(type, ==, "sl_filemeta_t")) {
+ offset = sl_pack_filemeta(query->dd_talloc_array[n], buf, offset, toc_buf, toc_idx);
} else if (STRCMP(type, ==, "uint64_t")) {
uint64_t i;
memcpy(&i, query->dd_talloc_array[n], sizeof(uint64_t));
i = 0;
while (i++ < count) {
query_data64 = sl_unpack_uint64(buf, offset, encoding);
- dalloc_add(query, &query_data64, uint64_t);
+ dalloc_add_copy(query, &query_data64, uint64_t);
offset += 8;
}
query_data64 = sl_unpack_uint64(buf, offset, encoding) >> 24;
t.tv_sec = query_data64 - SPOTLIGHT_TIME_DELTA;
t.tv_usec = 0;
- dalloc_add(query, &t, sl_time_t);
+ dalloc_add_copy(query, &t, sl_time_t);
offset += 8;
}
i = 0;
while (i++ < count) {
memcpy(uuid.sl_uuid, buf + offset, 16);
- dalloc_add(query, &uuid, sl_uuid_t);
+ dalloc_add_copy(query, &uuid, sl_uuid_t);
offset += 16;
}
ieee_fp_union.w[1] = RIVAL(buf, offset);
#endif
}
- dalloc_add(query, &ieee_fp_union.d, double);
+ dalloc_add_copy(query, &ieee_fp_union.d, double);
offset += 8;
}
EC_INIT;
int count;
uint64_t query_data64;
- sl_cnids_t cnids;
+ sl_cnids_t *cnids;
- EC_NULL( cnids.ca_cnids = talloc_zero(query, DALLOC_CTX) );
+ EC_NULL( cnids = talloc_zero(query, sl_cnids_t) );
+ EC_NULL( cnids->ca_cnids = talloc_zero(cnids, DALLOC_CTX) );
if (length <= 16)
/* that's permitted, it's an empty array */
query_data64 = sl_unpack_uint64(buf, offset, encoding);
count = query_data64 & 0xffff;
- cnids.ca_unkn1 = (query_data64 & 0xffff0000) >> 16;
- cnids.ca_context = query_data64 >> 32;
+ cnids->ca_unkn1 = (query_data64 & 0xffff0000) >> 16;
+ cnids->ca_context = query_data64 >> 32;
offset += 8;
while (count --) {
query_data64 = sl_unpack_uint64(buf, offset, encoding);
- dalloc_add(cnids.ca_cnids, &query_data64, uint64_t);
+ dalloc_add_copy(cnids->ca_cnids, &query_data64, uint64_t);
offset += 8;
}
- dalloc_add(query, &cnids, sl_cnids_t);
+ dalloc_add(query, cnids, sl_cnids_t);
EC_CLEANUP:
EC_EXIT;
}
}
-static int spotlight_dissect_loop(DALLOC_CTX *query,
- const char *buf,
- uint offset,
- uint count,
- const uint toc_offset,
- const uint encoding)
+static int sl_unpack_cpx(DALLOC_CTX *query,
+ const char *buf,
+ const int offset,
+ uint cpx_query_type,
+ uint cpx_query_count,
+ const uint toc_offset,
+ const uint encoding)
{
EC_INIT;
- int i, toc_index, query_length;
- uint subcount, cpx_query_type, cpx_query_count;
- uint64_t query_data64, query_type;
+
+ int roffset = offset;
+ uint64_t query_data64;
uint unicode_encoding;
uint8_t mark_exists;
char *p;
- int padding, slen;
+ int qlen, used_in_last_block, slen;
+ sl_array_t *sl_array;
+ sl_dict_t *sl_dict;
+ sl_filemeta_t *sl_fm;
+
+ switch (cpx_query_type) {
+ case SQ_CPX_TYPE_ARRAY:
+ sl_array = talloc_zero(query, sl_array_t);
+ EC_NEG1_LOG( roffset = sl_unpack_loop(sl_array, buf, offset, cpx_query_count, toc_offset, encoding) );
+ dalloc_add(query, sl_array, sl_array_t);
+ break;
+
+ case SQ_CPX_TYPE_DICT:
+ sl_dict = talloc_zero(query, sl_dict_t);
+ EC_NEG1_LOG( roffset = sl_unpack_loop(sl_dict, buf, offset, cpx_query_count, toc_offset, encoding) );
+ dalloc_add(query, sl_dict, sl_dict_t);
+ break;
+
+ case SQ_CPX_TYPE_STRING:
+ case SQ_CPX_TYPE_UTF16_STRING:
+ query_data64 = sl_unpack_uint64(buf, offset, encoding);
+ qlen = (query_data64 & 0xffff) * 8;
+ used_in_last_block = query_data64 >> 32;
+ slen = qlen - 8 + used_in_last_block;
+
+ if (cpx_query_type == SQ_CPX_TYPE_STRING) {
+ p = dalloc_strndup(query, buf + offset + 8, slen);
+ } else {
+ unicode_encoding = spotlight_get_utf16_string_encoding(buf, offset + 8, slen, encoding);
+ mark_exists = (unicode_encoding & SL_ENC_UTF_16);
+ unicode_encoding &= ~SL_ENC_UTF_16;
+ EC_NEG1( convert_string_allocate(CH_UCS2, CH_UTF8, buf + offset + (mark_exists ? 18 : 16), slen, &p) );
+ }
+
+ dalloc_add(query, p, char *);
+ roffset += qlen;
+ break;
+
+ case SQ_CPX_TYPE_FILEMETA:
+ query_data64 = sl_unpack_uint64(buf, offset, encoding);
+ qlen = (query_data64 & 0xffff) * 8;
+ if (qlen <= 8) {
+ EC_FAIL_LOG("SQ_CPX_TYPE_FILEMETA: query_length <= 8: %d", qlen);
+ } else {
+ sl_fm = talloc_zero(query, sl_filemeta_t);
+ EC_NEG1_LOG( sl_unpack(sl_fm, buf + offset + 8) );
+ dalloc_add(query, sl_fm, sl_filemeta_t);
+ }
+ roffset += qlen;
+ break;
+
+ case SQ_CPX_TYPE_CNIDS:
+ query_data64 = sl_unpack_uint64(buf, offset, encoding);
+ qlen = (query_data64 & 0xffff) * 8;
+ EC_NEG1_LOG( sl_unpack_CNID(query, buf, offset + 8, qlen, encoding) );
+ roffset += qlen;
+ break;
+
+ default:
+ EC_FAIL;
+ }
+
+EC_CLEANUP:
+ if (ret != 0)
+ roffset = -1;
+ return roffset;
+}
+
+static int sl_unpack_loop(DALLOC_CTX *query,
+ const char *buf,
+ int offset,
+ uint count,
+ const uint toc_offset,
+ const uint encoding)
+{
+ EC_INIT;
+ int i, toc_index, query_length;
+ uint subcount;
+ uint64_t query_data64, query_type;
+ uint cpx_query_type, cpx_query_count;
+ sl_nil_t nil;
+ sl_bool_t b;
while (count > 0 && (offset < toc_offset)) {
query_data64 = sl_unpack_uint64(buf, offset, encoding);
cpx_query_type = (query_data64 & 0xffff0000) >> 16;
cpx_query_count = query_data64 >> 32;
- switch (cpx_query_type) {
- case SQ_CPX_TYPE_ARRAY: {
- sl_array_t *sl_arrary = talloc_zero(query, sl_array_t);
- EC_NEG1_LOG( offset = spotlight_dissect_loop(sl_arrary, buf, offset + 8, cpx_query_count, toc_offset, encoding) );
- dalloc_add(query, sl_arrary, sl_array_t);
- break;
- }
-
- case SQ_CPX_TYPE_DICT: {
- sl_dict_t *sl_dict = talloc_zero(query, sl_dict_t);
- EC_NEG1_LOG( offset = spotlight_dissect_loop(sl_dict, buf, offset + 8, cpx_query_count, toc_offset, encoding) );
- dalloc_add(query, sl_dict, sl_dict_t);
- break;
- }
- case SQ_CPX_TYPE_STRING:
- query_data64 = sl_unpack_uint64(buf, offset + 8, encoding);
- query_length += (query_data64 & 0xffff) * 8;
- if ((padding = 8 - (query_data64 >> 32)) < 0)
- EC_FAIL;
- if ((slen = query_length - 16 - padding) < 1)
- EC_FAIL;
- p = talloc_strndup(query, buf + offset + 16, slen);
- dalloc_add(query, &p, char *);
- break;
-
- case SQ_CPX_TYPE_UTF16_STRING:
- query_data64 = sl_unpack_uint64(buf, offset + 8, encoding);
- query_length += (query_data64 & 0xffff) * 8;
- if ((padding = 8 - (query_data64 >> 32)) < 0)
- EC_FAIL;
- if ((slen = query_length - 16 - padding) < 1)
- EC_FAIL;
-
- unicode_encoding = spotlight_get_utf16_string_encoding(buf, offset + 16, slen, encoding);
- mark_exists = (unicode_encoding & SL_ENC_UTF_16);
- unicode_encoding &= ~SL_ENC_UTF_16;
-
- EC_NEG1( convert_string_allocate(CH_UCS2, CH_UTF8, buf + offset + (mark_exists ? 18 : 16), slen, &p) );
- dalloc_add(query, &p, char *);
- break;
-
- case SQ_CPX_TYPE_FILEMETA:
- query_data64 = sl_unpack_uint64(buf, offset + 8, encoding);
- query_length += (query_data64 & 0xffff) * 8;
-
- if (query_length <= 8) {
- EC_FAIL_LOG("SQ_CPX_TYPE_FILEMETA: query_length <= 8%s", "");
- } else {
- EC_NEG1_LOG( sl_unpack(query, buf + offset + 16) );
- }
- break;
-
- case SQ_CPX_TYPE_CNIDS:
- query_data64 = sl_unpack_uint64(buf, offset + 8, encoding);
- query_length += (query_data64 & 0xffff) * 8;
- EC_NEG1_LOG( sl_unpack_CNID(query, buf, offset + 16, query_length, encoding) );
- break;
- } /* switch (cpx_query_type) */
-
+ EC_NEG1_LOG( offset = sl_unpack_cpx(query, buf, offset + 8, cpx_query_type, cpx_query_count, toc_offset, encoding));
count--;
break;
-
- case SQ_TYPE_NULL: {
+ case SQ_TYPE_NULL:
subcount = query_data64 >> 32;
if (subcount > 64)
EC_FAIL;
- sl_nil_t nil = 0;
+ nil = 0;
for (i = 0; i < subcount; i++)
- dalloc_add(query, &nil, sl_nil_t);
+ dalloc_add_copy(query, &nil, sl_nil_t);
+ offset += query_length;
count -= subcount;
break;
- }
- case SQ_TYPE_BOOL: {
- sl_bool_t b = query_data64 >> 32;
- dalloc_add(query, &b, sl_bool_t);
+ case SQ_TYPE_BOOL:
+ b = query_data64 >> 32;
+ dalloc_add_copy(query, &b, sl_bool_t);
+ offset += query_length;
count--;
break;
- }
case SQ_TYPE_INT64:
EC_NEG1_LOG( subcount = sl_unpack_ints(query, buf, offset, encoding) );
+ offset += query_length;
count -= subcount;
break;
case SQ_TYPE_UUID:
EC_NEG1_LOG( subcount = sl_unpack_uuid(query, buf, offset, encoding) );
+ offset += query_length;
count -= subcount;
break;
case SQ_TYPE_FLOAT:
EC_NEG1_LOG( subcount = sl_unpack_floats(query, buf, offset, encoding) );
+ offset += query_length;
count -= subcount;
break;
case SQ_TYPE_DATE:
EC_NEG1_LOG( subcount = sl_unpack_date(query, buf, offset, encoding) );
+ offset += query_length;
count -= subcount;
break;
default:
EC_FAIL;
}
-
- offset += query_length;
}
EC_CLEANUP:
toc_entries = (int)(sl_unpack_uint64(buf, toc_offset, encoding) & 0xffff);
- EC_NEG1( spotlight_dissect_loop(query, buf, 0, 1, toc_offset + 8, encoding) );
+ EC_NEG1( sl_unpack_loop(query, buf, 0, 1, toc_offset + 8, encoding) );
EC_CLEANUP:
EC_EXIT;