#include <atalk/netatalk_conf.h>
#include <atalk/volume.h>
#include <atalk/dsi.h>
-
-#include "spotlight.h"
+#include <atalk/spotlight.h>
#define MAX_SLQ_DAT (DSI_DATASIZ - 64)
#define MAX_SLQ_TOC 8192
static uint spotlight_get_utf16_string_encoding(const char *buf, int offset, int query_length, uint encoding) {
uint utf16_encoding;
- /* check for byte order mark */
- utf16_encoding = SL_ENC_BIG_ENDIAN;
- if (query_length >= 2) {
- uint16_t byte_order_mark;
- if (encoding == SL_ENC_LITTLE_ENDIAN)
- byte_order_mark = SVAL(buf, offset);
- else
- byte_order_mark = RSVAL(buf, offset);
+ /* Assumed encoding in absence of a bom is little endian */
+ utf16_encoding = SL_ENC_LITTLE_ENDIAN;
- if (byte_order_mark == 0xFFFE) {
- utf16_encoding = SL_ENC_BIG_ENDIAN | SL_ENC_UTF_16;
- }
- else if (byte_order_mark == 0xFEFF) {
+ if (query_length >= 2) {
+ uint8_t le_bom[] = {0xff, 0xfe};
+ uint8_t be_bom[] = {0xfe, 0xff};
+ if (memcmp(le_bom, buf + offset, sizeof(uint16_t)) == 0)
utf16_encoding = SL_ENC_LITTLE_ENDIAN | SL_ENC_UTF_16;
- }
+ else if (memcmp(be_bom, buf + offset, sizeof(uint16_t)) == 0)
+ utf16_encoding = SL_ENC_BIG_ENDIAN | SL_ENC_UTF_16;
}
return utf16_encoding;
static int sl_pack_CNID(sl_cnids_t *cnids, char *buf, int offset, char *toc_buf, int *toc_idx)
{
EC_INIT;
- int off = 0, len;
+ int len;
int cnid_count = talloc_array_length(cnids->ca_cnids->dd_talloc_array);
uint64_t id;
offset += 8;
if (cnid_count > 0) {
- EC_ZERO( slvalc(buf, offset, MAX_SLQ_DAT, sl_pack_tag(0x0add, cnid_count, cnids->ca_context)) );
+ EC_ZERO( slvalc(buf, offset, MAX_SLQ_DAT, sl_pack_tag(cnids->ca_unkn1, cnid_count, cnids->ca_context)) );
offset += 8;
for (int i = 0; i < cnid_count; i++) {
{
int count, i;
uint64_t query_data64;
- double fval;
union {
double d;
uint32_t w[2];
uint64_t query_data64;
uint unicode_encoding;
uint8_t mark_exists;
- char *p;
+ char *p, *tmp;
int qlen, used_in_last_block, slen;
sl_array_t *sl_array;
sl_dict_t *sl_dict;
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;
+ slen = qlen - 16 + 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) );
+ if (unicode_encoding & SL_ENC_BIG_ENDIAN)
+ EC_FAIL_LOG("Unsupported big endian UTF16 string");
+ slen -= mark_exists ? 2 : 0;
+ EC_NEG1( convert_string_allocate(CH_UCS2,
+ CH_UTF8,
+ buf + offset + (mark_exists ? 10 : 8),
+ slen,
+ &tmp) );
+ p = dalloc_strndup(query, tmp, strlen(tmp));
+ free(tmp);
}
dalloc_add(query, p, char *);
int sl_unpack(DALLOC_CTX *query, const char *buf)
{
EC_INIT;
- int encoding, i, toc_entries;
- uint64_t toc_offset, tquerylen, toc_entry;
+ int encoding, toc_entries;
+ uint64_t toc_offset;
if (strncmp(buf, "md031234", 8) == 0)
encoding = SL_ENC_BIG_ENDIAN;