X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fspotlight_marshalling.c;h=69733f4943676c58ec4baf7e1d20105a17d97503;hb=9b30356782a792ad0ebcf36fe4a4f276cb8e9d76;hp=a30145e90e6219d00ca00f2c31c7172d6de5d017;hpb=4350426e2528a5765642f388e06e9ac6ff75fafd;p=netatalk.git diff --git a/etc/afpd/spotlight_marshalling.c b/etc/afpd/spotlight_marshalling.c index a30145e9..69733f49 100644 --- a/etc/afpd/spotlight_marshalling.c +++ b/etc/afpd/spotlight_marshalling.c @@ -33,8 +33,7 @@ #include #include #include - -#include "spotlight.h" +#include #define MAX_SLQ_DAT (DSI_DATASIZ - 64) #define MAX_SLQ_TOC 8192 @@ -101,21 +100,16 @@ static int slvalc(char *buf, off_t off, off_t maxoff, uint64_t val) 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; @@ -239,7 +233,7 @@ static int sl_pack_CNID(sl_cnids_t *cnids, char *buf, int offset, char *toc_buf, 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++) { @@ -604,7 +598,7 @@ static int sl_unpack_cpx(DALLOC_CTX *query, 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; @@ -628,15 +622,23 @@ static int sl_unpack_cpx(DALLOC_CTX *query, 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 *);