X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/89b3af67bb32e691275bf6fa803d1834b2284115..c18c124eaa464aaaa5549e99e5a70fc9cbb50944:/bsd/hfs/hfs_encodings.c diff --git a/bsd/hfs/hfs_encodings.c b/bsd/hfs/hfs_encodings.c index a4272c19b..d4fc65fc6 100644 --- a/bsd/hfs/hfs_encodings.c +++ b/bsd/hfs/hfs_encodings.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2013 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -26,12 +26,21 @@ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ +#include +#include + +#if HFS + #include #include #include #include #include #include +#include +#include +#include +#include #include "hfs.h" @@ -46,28 +55,21 @@ SLIST_HEAD(encodinglst, hfs_encoding) hfs_encoding_list = {0}; lck_mtx_t encodinglst_mutex; - - /* hfs encoding converter entry */ struct hfs_encoding { SLIST_ENTRY(hfs_encoding) link; int refcount; int kmod_id; - UInt32 encoding; + u_int32_t encoding; hfs_to_unicode_func_t get_unicode_func; unicode_to_hfs_func_t get_hfsname_func; }; -/* XXX We should use an "official" interface! */ -extern kern_return_t kmod_destroy(host_priv_t host_priv, kmod_t id); -extern struct host realhost; - #define MAX_HFS_UNICODE_CHARS (15*5) -int mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, UInt32 maxCharLen, UInt32 *usedCharLen); - -static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs_str); - +#if CONFIG_HFS_STD +static int unicode_to_mac_roman(UniChar *uni_str, u_int32_t unicodeChars, Str31 hfs_str); +#endif void hfs_converterinit(void) @@ -80,14 +82,62 @@ hfs_converterinit(void) lck_mtx_init(&encodinglst_mutex, encodinglst_lck_grp, encodinglst_lck_attr); +#if CONFIG_HFS_STD /* * add resident MacRoman converter and take a reference - * since its always "loaded". + * since its always "loaded". MacRoman is the default converter + * for HFS standard volumes. + * + * Only do this if we are actually supporting HFS standard + * volumes. The converter is not used on configurations + * that do not support HFS standard. */ hfs_addconverter(0, kTextEncodingMacRoman, mac_roman_to_unicode, unicode_to_mac_roman); SLIST_FIRST(&hfs_encoding_list)->refcount++; +#endif + +} + +#if !CONFIG_HFS_STD + +/* + * Function stubs are needed for KPI export. + * It is a little swizzly to have two separate copies of the stub functions in this file + * but the prototypes of these functions are different if we're using the real headers + * vs. the dummy prototypes at the end of the file. (hfs_to_unicode_func_t vs. void*) + * + * As a result, we need our own copies in the no-HFS-Standard configuration + */ +int hfs_addconverter( __unused int id, + __unused u_int32_t encoding, + __unused hfs_to_unicode_func_t get_unicode, + __unused unicode_to_hfs_func_t get_hfsname ) +{ + return(0); } +int hfs_getconverter( __unused u_int32_t encoding, + __unused hfs_to_unicode_func_t *get_unicode, + __unused unicode_to_hfs_func_t *get_hfsname) +{ + return(EINVAL); +} + +int hfs_relconverter(__unused u_int32_t encoding) +{ + return(EINVAL); +} + +int hfs_remconverter(__unused int id, __unused u_int32_t encoding) +{ + return(0); +} + +#else + +/* + * For configurations that do support HFS standard, we need all of these.. + */ /* * hfs_addconverter - add an HFS encoding converter @@ -98,7 +148,7 @@ hfs_converterinit(void) * */ int -hfs_addconverter(int id, UInt32 encoding, hfs_to_unicode_func_t get_unicode, unicode_to_hfs_func_t get_hfsname) +hfs_addconverter(int id, u_int32_t encoding, hfs_to_unicode_func_t get_unicode, unicode_to_hfs_func_t get_hfsname) { struct hfs_encoding *encp; @@ -131,7 +181,7 @@ hfs_addconverter(int id, UInt32 encoding, hfs_to_unicode_func_t get_unicode, uni * The call is initiated from within the kernel during the unmounting of an hfs voulume. */ int -hfs_remconverter(int id, UInt32 encoding) +hfs_remconverter(int id, u_int32_t encoding) { struct hfs_encoding *encp; @@ -165,7 +215,7 @@ hfs_remconverter(int id, UInt32 encoding) * Normally called during the mounting of an hfs voulume. */ int -hfs_getconverter(UInt32 encoding, hfs_to_unicode_func_t *get_unicode, unicode_to_hfs_func_t *get_hfsname) +hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode, unicode_to_hfs_func_t *get_hfsname) { struct hfs_encoding *encp; int found = 0; @@ -198,7 +248,7 @@ hfs_getconverter(UInt32 encoding, hfs_to_unicode_func_t *get_unicode, unicode_to * Normally called during the unmounting of an hfs voulume. */ int -hfs_relconverter(UInt32 encoding) +hfs_relconverter(u_int32_t encoding) { struct hfs_encoding *encp; @@ -209,13 +259,13 @@ hfs_relconverter(UInt32 encoding) /* if converter is no longer in use, release it */ if (encp->refcount <= 0 && encp->kmod_id != 0) { - int id = encp->kmod_id; + uint32_t loadTag = (uint32_t)encp->kmod_id; SLIST_REMOVE(&hfs_encoding_list, encp, hfs_encoding, link); lck_mtx_unlock(&encodinglst_mutex); FREE(encp, M_TEMP); - kmod_destroy((host_priv_t) host_priv_self(), id); + (void)OSKextUnloadKextWithLoadTag(loadTag); return (0); } lck_mtx_unlock(&encodinglst_mutex); @@ -227,7 +277,6 @@ hfs_relconverter(UInt32 encoding) return (EINVAL); } - /* * Convert HFS encoded string into UTF-8 * @@ -235,14 +284,26 @@ hfs_relconverter(UInt32 encoding) * '/' chars are converted to ':' */ int -hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, unsigned char* dstStr) +hfs_to_utf8(ExtendedVCB *vcb, const Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, unsigned char* dstStr) { int error; UniChar uniStr[MAX_HFS_UNICODE_CHARS]; ItemCount uniCount; size_t utf8len; hfs_to_unicode_func_t hfs_get_unicode = VCBTOHFS(vcb)->hfs_get_unicode; + u_int8_t pascal_length = 0; + /* + * Validate the length of the Pascal-style string before passing it + * down to the decoding engine. + */ + pascal_length = *((const u_int8_t*)(hfs_str)); + if (pascal_length > 31) { + /* invalid string; longer than 31 bytes */ + error = EINVAL; + return error; + } + error = hfs_get_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount); if (uniCount == 0) @@ -259,18 +320,29 @@ hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen, ByteCount *act return error; } - /* * When an HFS name cannot be encoded with the current * volume encoding then MacRoman is used as a fallback. */ int -mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, unsigned char* dstStr) +mac_roman_to_utf8(const Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, unsigned char* dstStr) { int error; UniChar uniStr[MAX_HFS_UNICODE_CHARS]; ItemCount uniCount; size_t utf8len; + u_int8_t pascal_length = 0; + + /* + * Validate the length of the Pascal-style string before passing it + * down to the decoding engine. + */ + pascal_length = *((const u_int8_t*)(hfs_str)); + if (pascal_length > 31) { + /* invalid string; longer than 31 bytes */ + error = EINVAL; + return error; + } error = mac_roman_to_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount); @@ -288,7 +360,6 @@ mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, u return error; } - /* * Convert Unicode string into HFS encoding * @@ -328,6 +399,7 @@ utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr, Str return error; } + int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr) { @@ -348,7 +420,7 @@ utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr) */ /* 0x00A0 - 0x00FF = Latin 1 Supplement (30 total) */ -static UInt8 gLatin1Table[] = { +static u_int8_t gLatin1Table[] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x00A0 */ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, '?', 0xA4, 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, '?', 0xA8, 0xF8, /* 0x00B0 */ 0xA1, 0XB1, '?', '?', 0xAB, 0xB5, 0xA6, 0xe1, 0xFC, '?', 0xBC, 0xC8, '?', '?', '?', 0xC0, @@ -359,14 +431,14 @@ static UInt8 gLatin1Table[] = { }; /* 0x02C0 - 0x02DF = Spacing Modifiers (8 total) */ -static UInt8 gSpaceModsTable[] = { +static u_int8_t gSpaceModsTable[] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x02C0 */ '?', '?', '?', '?', '?', '?', 0xF6, 0xFF, '?', '?', '?', '?', '?', '?', '?', '?', /* 0x02D0 */ '?', '?', '?', '?', '?', '?', '?', '?', 0xF9, 0xFA, 0xFB, 0xFE, 0xF7, 0xFD, '?', '?' }; /* 0x2010 - 0x20AF = General Punctuation (17 total) */ -static UInt8 gPunctTable[] = { +static u_int8_t gPunctTable[] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x2010 */ '?', '?', '?', 0xd0, 0xd1, '?', '?', '?', 0xd4, 0xd5, 0xe2, '?', 0xd2, 0xd3, 0xe3, '?', /* 0x2020 */ 0xa0, 0xe0, 0xa5, '?', '?', '?', 0xc9, '?', '?', '?', '?', '?', '?', '?', '?', '?', @@ -381,7 +453,7 @@ static UInt8 gPunctTable[] = { }; /* 0x22xx = Mathematical Operators (11 total) */ -static UInt8 gMathTable[] = { +static u_int8_t gMathTable[] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x2200 */ '?', '?', 0xb6, '?', '?', '?', 0xc6, '?', '?', '?', '?', '?', '?', '?', '?', 0xb8, /* 0x2210 */ '?', 0xb7, '?', '?', '?', '?', '?', '?', '?', '?', 0xc3, '?', '?', '?', 0xb0, '?', @@ -393,7 +465,7 @@ static UInt8 gMathTable[] = { }; /* */ -static UInt8 gReverseCombTable[] = { +static u_int8_t gReverseCombTable[] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x40 */ 0xDA, 0x40, 0xDA, 0xDA, 0xDA, 0x56, 0xDA, 0xDA, 0xDA, 0x6C, 0xDA, 0xDA, 0xDA, 0xDA, 0x82, 0x98, /* 0x50 */ 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xAE, 0xDA, 0xDA, 0xDA, 0xC4, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, @@ -454,18 +526,18 @@ static UInt8 gReverseCombTable[] = { * * Assumes Unicode input is fully decomposed */ -static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs_str) +static int unicode_to_mac_roman(UniChar *uni_str, u_int32_t unicodeChars, Str31 hfs_str) { - UInt8 *p; + u_int8_t *p; const UniChar *u; UniChar c; UniChar mask; - UInt16 inputChars; - UInt16 pascalChars; + u_int16_t inputChars; + u_int16_t pascalChars; OSErr result = noErr; - UInt8 lsb; - UInt8 prevChar; - UInt8 mc; + u_int8_t lsb; + u_int8_t prevChar; + u_int8_t mc; mask = (UniChar) 0xFF80; p = &hfs_str[1]; @@ -475,7 +547,7 @@ static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs while (inputChars) { c = *(u++); - lsb = (UInt8) c; + lsb = (u_int8_t) c; /* * If its not 7-bit ascii, then we need to map it @@ -499,7 +571,7 @@ static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs break; case 0x2200: - if (lsb <= 0x68) + if (lsb < 0x68) mc = gMathTable[lsb]; break; @@ -629,12 +701,12 @@ static UniChar gHiBitCombUnicode[128] = { */ int mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, - UInt32 maxCharLen, UInt32 *unicodeChars) + __unused u_int32_t maxCharLen, u_int32_t *unicodeChars) { - const UInt8 *p; + const u_int8_t *p; UniChar *u; - UInt16 pascalChars; - UInt8 c; + u_int16_t pascalChars; + u_int8_t c; p = hfs_str; u = uni_str; @@ -644,7 +716,7 @@ mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, while (pascalChars--) { c = *(p++); - if ( (SInt8) c >= 0 ) { /* check if seven bit ascii */ + if ( (int8_t) c >= 0 ) { /* check if seven bit ascii */ *(u++) = (UniChar) c; /* just pad high byte with zero */ } else { /* its a hi bit character */ UniChar uc; @@ -666,3 +738,44 @@ mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, return noErr; } +#endif /* CONFIG_STD_HFS */ + +#else /* not HFS */ + +/* + * These function prototypes are here because hfs.h is not #included + * so its prototypes are not provided. These are needed because they are exported + * as KPI for the conversion subroutines during mounting of HFS standard. + */ +int hfs_addconverter(int id, u_int32_t encoding, void * get_unicode, void * get_hfsname); +int hfs_getconverter(u_int32_t encoding, void *get_unicode, void *get_hfsname); +int hfs_relconverter(u_int32_t encoding); +int hfs_remconverter(int id, u_int32_t encoding); + +/* Function stubs are needed for KPI export */ + +int hfs_addconverter( __unused int id, + __unused u_int32_t encoding, + __unused void * get_unicode, + __unused void * get_hfsname ) +{ + return(0); +} + +int hfs_getconverter(__unused u_int32_t encoding, __unused void *get_unicode, __unused void *get_hfsname) +{ + return(EINVAL); +} + +int hfs_relconverter(__unused u_int32_t encoding) +{ + return(EINVAL); +} + +int hfs_remconverter(__unused int id, __unused u_int32_t encoding) +{ + return(0); +} +#endif + +