From e962a853db003df4e563927d0171c9a8968454a8 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 15 Dec 2016 17:59:42 +0000 Subject: [PATCH 1/1] hfs-366.30.3.tar.gz --- .gitignore | 3 + core/hfs_attrlist.c | 15 ++-- core/hfs_catalog.c | 18 +++- fsck_hfs/fsck_messages.c | 138 ++++++++++++++++++++++++++++--- hfs_encodings/hfs_encodinghint.c | 2 +- 5 files changed, 154 insertions(+), 22 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f88684 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.xccheckout +*.xcscmblueprint +xcuserdata/ diff --git a/core/hfs_attrlist.c b/core/hfs_attrlist.c index c7ddf3d..c6ae99f 100644 --- a/core/hfs_attrlist.c +++ b/core/hfs_attrlist.c @@ -514,7 +514,7 @@ hfs_readdirattr_internal(struct vnode *dvp, struct attrlist *alist, * Do not use the valence as a way to determine if we hit EOF, since * it can be wrong. Use the catalog's output only. */ - if ((*(eofflag) == 0) && (lastdescp != NULL) && (lastdescp->cd_nameptr != NULL)) { + if ((*(eofflag) == 0) && (lastdescp != NULL)) { /* Remember last entry */ if ((dirhint->dh_desc.cd_flags & CD_HASBUF) && @@ -522,10 +522,15 @@ hfs_readdirattr_internal(struct vnode *dvp, struct attrlist *alist, dirhint->dh_desc.cd_flags &= ~CD_HASBUF; vfs_removename((const char *)dirhint->dh_desc.cd_nameptr); } - dirhint->dh_desc.cd_namelen = lastdescp->cd_namelen; - dirhint->dh_desc.cd_nameptr = (const u_int8_t *) - vfs_addname((const char *)lastdescp->cd_nameptr, lastdescp->cd_namelen, 0, 0); - dirhint->dh_desc.cd_flags |= CD_HASBUF; + if (lastdescp->cd_nameptr != NULL) { + dirhint->dh_desc.cd_namelen = lastdescp->cd_namelen; + dirhint->dh_desc.cd_nameptr = (const u_int8_t *) + vfs_addname((const char *)lastdescp->cd_nameptr, lastdescp->cd_namelen, 0, 0); + dirhint->dh_desc.cd_flags |= CD_HASBUF; + } else { + dirhint->dh_desc.cd_namelen = 0; + dirhint->dh_desc.cd_nameptr = NULL; + } dirhint->dh_index = index - 1; dirhint->dh_desc.cd_cnid = lastdescp->cd_cnid; dirhint->dh_desc.cd_hint = lastdescp->cd_hint; diff --git a/core/hfs_catalog.c b/core/hfs_catalog.c index b1b25da..a70d32e 100644 --- a/core/hfs_catalog.c +++ b/core/hfs_catalog.c @@ -1136,6 +1136,7 @@ exit: /* * cat_create - create a node in the catalog + * using MacRoman encoding * * NOTE: both the catalog file and attribute file locks must * be held before calling this function. @@ -1400,14 +1401,23 @@ cat_rename ( } /* - * Update the text encoding (on disk and in descriptor). + * Update the text encoding (on disk and in descriptor), + * using hfs_pickencoding to get the new encoding when available. * * Note that hardlink inodes don't require a text encoding hint. */ if (!std_hfs && todir_cdp->cd_parentcnid != hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid && todir_cdp->cd_parentcnid != hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) { - recp->hfsPlusFile.textEncoding = kTextEncodingMacUnicode; +#if !TARGET_OS_EMBEDDED + encoding = hfs_pickencoding(to_key->nodeName.unicode, to_key->nodeName.length); +#else + encoding = kTextEncodingMacRoman; +#endif + hfs_setencodingbits(hfsmp, encoding); + recp->hfsPlusFile.textEncoding = encoding; + if (out_cdp) + out_cdp->cd_encoding = encoding; } #if CONFIG_HFS_STD @@ -3220,8 +3230,8 @@ getdirentries_callback(const CatalogKey *ckp, const CatalogRecord *crp, namelen = cnp->ustr.length; /* - * For MacRoman encoded names, assume that its ascii and - * convert it directly in an attempt to avoid the more + * For MacRoman encoded names (textEncoding == 0), assume that it's ascii + * and convert it directly in an attempt to avoid the more * expensive utf8_encodestr conversion. */ if ((namelen < maxnamelen) && (crp->hfsPlusFile.textEncoding == 0)) { diff --git a/fsck_hfs/fsck_messages.c b/fsck_hfs/fsck_messages.c index 4047941..0e10d7e 100644 --- a/fsck_hfs/fsck_messages.c +++ b/fsck_hfs/fsck_messages.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "fsck_messages.h" #include "fsck_keys.h" @@ -776,6 +777,107 @@ fsckPrintString(struct context *ctx, fsck_message_t *m, va_list ap) return 0; } +static char* escapeCharactersXML(char *input_string) +{ + if (input_string == NULL) { + return NULL; + } + + char *output_string = NULL; + + // In the worst case, each character of the input_string could be a special character, + // Each special character can add at most 5 extra characters to the string. + char temp[MAXPATHLEN*6 + 1]; + memset(temp, 0, MAXPATHLEN*6 + 1); + + char *input_ptr = input_string; + char *temp_ptr = &temp[0]; + + while(*input_ptr != '\0') { + char c = *input_ptr; + + switch (c) { + case '&': { + *temp_ptr = '&'; + ++temp_ptr; + *temp_ptr = 'a'; + ++temp_ptr; + *temp_ptr = 'm'; + ++temp_ptr; + *temp_ptr = 'p'; + ++temp_ptr; + *temp_ptr = ';'; + ++temp_ptr; + break; + } + + case '<': { + *temp_ptr = '&'; + ++temp_ptr; + *temp_ptr = 'l'; + ++temp_ptr; + *temp_ptr = 't'; + ++temp_ptr; + *temp_ptr = ';'; + ++temp_ptr; + break; + } + + case '>': { + *temp_ptr = '&'; + ++temp_ptr; + *temp_ptr = 'g'; + ++temp_ptr; + *temp_ptr = 't'; + ++temp_ptr; + *temp_ptr = ';'; + ++temp_ptr; + break; + } + + case '"': { + *temp_ptr = '&'; + ++temp_ptr; + *temp_ptr = 'q'; + ++temp_ptr; + *temp_ptr = 'u'; + ++temp_ptr; + *temp_ptr = 'o'; + ++temp_ptr; + *temp_ptr = 't'; + ++temp_ptr; + *temp_ptr = ';'; + ++temp_ptr; + break; + } + + case '\'': { + *temp_ptr = '&'; + ++temp_ptr; + *temp_ptr = 'a'; + ++temp_ptr; + *temp_ptr = 'p'; + ++temp_ptr; + *temp_ptr = 'o'; + ++temp_ptr; + *temp_ptr = 's'; + ++temp_ptr; + *temp_ptr = ';'; + ++temp_ptr; + break; + } + default: { + *temp_ptr = c; + ++temp_ptr; + } + } + ++input_ptr; + } + + output_string = strdup((const char *)(&temp)); + return output_string; +} + /* * fsckPrintXML(context, message, va_list) * Print out a message in XML (well, plist) format. @@ -785,7 +887,7 @@ fsckPrintString(struct context *ctx, fsck_message_t *m, va_list ap) static int fsckPrintXML(struct context *ctx, fsck_message_t *m, va_list ap) { - char *newmsg = convertfmt(m->msg); + char *newmsg = convertfmt(m->msg); /* See convertfmt() for details */ if (newmsg == NULL) { return -1; @@ -828,22 +930,34 @@ fsckPrintXML(struct context *ctx, fsck_message_t *m, va_list ap) printargs(ctx, "\t\t\t%llu\n", x); } else if (m->argtype[i] == fsckTypeString) { char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s\n", p); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s\n", escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypePath) { - char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s %s\n", kfsckParamPathKey, p); + char *p = va_arg(ap, char*); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s %s\n", kfsckParamPathKey, escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypeFile) { - char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s %s\n", kfsckParamFileKey, p); + char *p = va_arg(ap, char*); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s %s\n", kfsckParamFileKey, escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypeDirectory) { - char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s %s\n", kfsckParamDirectoryKey, p); + char *p = va_arg(ap, char*); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s %s\n", kfsckParamDirectoryKey, escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypeVolume) { - char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s %s\n", kfsckParamVolumeKey, p); + char *p = va_arg(ap, char*); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s %s\n", kfsckParamVolumeKey, escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypeFSType) { - char *p = va_arg(ap, char*); - printargs(ctx, "\t\t\t%s %s\n", kfsckParamFSTypeKey, p); + char *p = va_arg(ap, char*); + char *escapedP = escapeCharactersXML(p); + printargs(ctx, "\t\t\t%s %s\n", kfsckParamFSTypeKey, escapedP); + free(escapedP); } else if (m->argtype[i] == fsckTypeProgress) { int x = va_arg(ap, int); printargs(ctx, "\t\t\t%d\n", x); diff --git a/hfs_encodings/hfs_encodinghint.c b/hfs_encodings/hfs_encodinghint.c index 917941e..a2cf7f3 100644 --- a/hfs_encodings/hfs_encodinghint.c +++ b/hfs_encodings/hfs_encodinghint.c @@ -741,7 +741,7 @@ static u_int8_t cjk_bitmap[] = { /* * Pick a suitable Mac encoding value for a Unicode string. * - * This routine is only used during file creation and renaming. + * This routine is only used during file renaming. */ u_int32_t hfs_pickencoding(const u_int16_t *src, int len) -- 2.45.2