]> git.saurik.com Git - apple/hfs.git/commitdiff
hfs-366.30.3.tar.gz macos-10122 macos-10123 v366.30.3
authorApple <opensource@apple.com>
Thu, 15 Dec 2016 17:59:42 +0000 (17:59 +0000)
committerApple <opensource@apple.com>
Thu, 15 Dec 2016 17:59:42 +0000 (17:59 +0000)
.gitignore [new file with mode: 0644]
core/hfs_attrlist.c
core/hfs_catalog.c
fsck_hfs/fsck_messages.c
hfs_encodings/hfs_encodinghint.c

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..7f88684
--- /dev/null
@@ -0,0 +1,3 @@
+*.xccheckout
+*.xcscmblueprint
+xcuserdata/
index c7ddf3d7a8687240b1482e0a229589719d150235..c6ae99fe1be3ed6f0bc2b611f9c45c79e5215b5e 100644 (file)
@@ -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;
index b1b25dabc7770c431d3effbbacb61a7ecf3b0c21..a70d32e603dbd922ed558c320a567eb806df1018 100644 (file)
@@ -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)) {
index 4047941a8a2b4d7c39dedc2d0831fb4b1d6b8953..0e10d7ee6be0cc9feb555161a3b05a02fa5d1837 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <assert.h>
 #include <Block.h>
+#include <sys/param.h>
 
 #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<integer>%llu</integer>\n", x);
                        } else if (m->argtype[i] == fsckTypeString) {
                                char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<string>%s</string>\n", p);
+                char *escapedP = escapeCharactersXML(p);
+                               printargs(ctx, "\t\t\t<string>%s</string>\n", escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypePath) {
-                               char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamPathKey, p);
+                char *p = va_arg(ap, char*);
+                char *escapedP = escapeCharactersXML(p);
+                printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamPathKey, escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypeFile) {
-                               char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamFileKey, p);
+                char *p = va_arg(ap, char*);
+                char *escapedP = escapeCharactersXML(p);
+                printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamFileKey, escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypeDirectory) {
-                               char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamDirectoryKey, p);
+                char *p = va_arg(ap, char*);
+                char *escapedP = escapeCharactersXML(p);
+                printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamDirectoryKey, escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypeVolume) {
-                               char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamVolumeKey, p);
+                char *p = va_arg(ap, char*);
+                char *escapedP = escapeCharactersXML(p);
+                printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamVolumeKey, escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypeFSType) {
-                               char *p = va_arg(ap, char*);
-                               printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamFSTypeKey, p);
+                char *p = va_arg(ap, char*);
+                char *escapedP = escapeCharactersXML(p);
+                printargs(ctx, "\t\t\t<dict><key>%s</key> <string>%s</string></dict>\n", kfsckParamFSTypeKey, escapedP);
+                free(escapedP);
                        } else if (m->argtype[i] == fsckTypeProgress) {
                                int x = va_arg(ap, int);
                                printargs(ctx, "\t\t\t<integer>%d</integer>\n", x); 
index 917941efbec79942d683e28c6cefe530df4ade59..a2cf7f3dd818bf84dd34e6ef55dcb9a52a7204b4 100644 (file)
@@ -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)