* 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) &&
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;
/*
* 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.
}
/*
- * 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
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)) {
#include <string.h>
#include <assert.h>
#include <Block.h>
+#include <sys/param.h>
#include "fsck_messages.h"
#include "fsck_keys.h"
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.
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;
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);