From 4eb41464746be999800391b9b3110a6d264622d6 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 14 Mar 2012 09:07:59 +0100 Subject: [PATCH] Improved standards compliance for ISO level 1 names with partly relaxed constraints. --- libisofs/ecma119_tree.c | 29 +++++++++++-- libisofs/libisofs.h | 2 +- libisofs/util.c | 95 ++++++++++++++++++++++++++++++++++++++--- libisofs/util.h | 10 ++++- 4 files changed, 124 insertions(+), 12 deletions(-) diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c index fe395e5..695b506 100644 --- a/libisofs/ecma119_tree.c +++ b/libisofs/ecma119_tree.c @@ -32,7 +32,7 @@ static int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name) { - int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len; + int ret, relaxed, free_ascii_name= 0, force_dots = 0; char *ascii_name; char *isoname= NULL; @@ -73,11 +73,22 @@ needs_transl:; } else if (img->max_37_char_filenames) { isoname = iso_r_dirid(ascii_name, 37, relaxed); } else if (img->iso_level == 1) { + +#ifdef Libisofs_old_ecma119_nameS + if (relaxed) { isoname = iso_r_dirid(ascii_name, 8, relaxed); } else { - isoname = iso_1_dirid(ascii_name); + isoname = iso_1_dirid(ascii_name, 0); } + +#else /* Libisofs_old_ecma119_nameS */ + + isoname = iso_1_dirid(ascii_name, relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + + } else { if (relaxed) { isoname = iso_r_dirid(ascii_name, 31, relaxed); @@ -94,6 +105,11 @@ needs_transl:; } else if (img->max_37_char_filenames) { isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots); } else if (img->iso_level == 1) { + +#ifdef Libisofs_old_ecma119_nameS + + int max_len; + if (relaxed) { if (strchr(ascii_name, '.') == NULL) max_len = 8; @@ -102,8 +118,15 @@ needs_transl:; isoname = iso_r_fileid(ascii_name, max_len, relaxed, force_dots); } else { - isoname = iso_1_fileid(ascii_name, force_dots); + isoname = iso_1_fileid(ascii_name, 0, force_dots); } + +#else /* Libisofs_old_ecma119_nameS */ + + isoname = iso_1_fileid(ascii_name, relaxed, force_dots); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } else { if (relaxed || !force_dots) { isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots); diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index c73cc75..fe322e0 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -1584,7 +1584,7 @@ int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags); int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow); /** - * Allow a single file or directory hierarchy to have up to 37 characters. + * Allow a single file or directory identifier to have up to 37 characters. * This is larger than the 31 characters allowed by ISO level 2, and the * extra space is taken from the version number, so this also forces * omit_version_numbers. diff --git a/libisofs/util.c b/libisofs/util.c index 2b4a532..d40bfe7 100644 --- a/libisofs/util.c +++ b/libisofs/util.c @@ -685,8 +685,27 @@ static int valid_j_char(uint16_t c) && cmp_ucsbe(&c, '\\'); } +static char map_fileid_char(char c, int relaxed) +{ + char upper; + + if (relaxed == 2) /* all chars are allowed */ + return c; + if (valid_d_char(c)) + return c; + upper= toupper(c); + if (valid_d_char(upper)) { + if (relaxed) { + /* lower chars are allowed */ + return c; + } + return upper; + } + return '_'; +} + static -char *iso_dirid(const char *src, int size) +char *iso_dirid(const char *src, int size, int relaxed) { size_t len, i; char name[32]; @@ -696,25 +715,35 @@ char *iso_dirid(const char *src, int size) len = size; } for (i = 0; i < len; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= toupper(src[i]); name[i] = valid_d_char(c) ? c : '_'; + +#else /* Libisofs_old_ecma119_nameS */ + + name[i] = map_fileid_char(src[i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } name[len] = '\0'; return strdup(name); } -char *iso_1_dirid(const char *src) +char *iso_1_dirid(const char *src, int relaxed) { - return iso_dirid(src, 8); + return iso_dirid(src, 8, relaxed); } char *iso_2_dirid(const char *src) { - return iso_dirid(src, 31); + return iso_dirid(src, 31, 0); } -char *iso_1_fileid(const char *src, int force_dots) +char *iso_1_fileid(const char *src, int relaxed, int force_dots) { char *dot; /* Position of the last dot in the filename, will be used * to calculate lname and lext. */ @@ -739,9 +768,22 @@ char *iso_1_fileid(const char *src, int force_dots) /* Convert up to 8 characters of the filename. */ for (i = 0; i < lname && i < 8; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= toupper(src[i]); dest[pos++] = valid_d_char(c) ? c : '_'; + +#else /* Libisofs_old_ecma119_nameS */ + + if (dot == NULL && src[i] == '.') + dest[pos++] = '_'; /* make sure that ignored dots do not appear */ + else + dest[pos++] = map_fileid_char(src[i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } /* This dot is mandatory, even if there is no extension. */ @@ -750,9 +792,19 @@ char *iso_1_fileid(const char *src, int force_dots) /* Convert up to 3 characters of the extension, if any. */ for (i = 0; i < lext && i < 3; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= toupper(src[lname + 1 + i]); dest[pos++] = valid_d_char(c) ? c : '_'; + +#else /* Libisofs_old_ecma119_nameS */ + + dest[pos++] = map_fileid_char(src[lname + 1 + i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } dest[pos] = '\0'; @@ -835,6 +887,9 @@ char *iso_r_dirid(const char *src, int size, int relaxed) if (dest == NULL) return NULL; for (i = 0; i < len; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= src[i]; if (relaxed == 2) { /* all chars are allowed */ @@ -855,6 +910,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed) dest[i] = '_'; } } + +#else /* Libisofs_old_ecma119_nameS */ + + dest[i] = map_fileid_char(src[i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } dest[len] = '\0'; @@ -862,7 +924,8 @@ char *iso_r_dirid(const char *src, int size, int relaxed) } /** - * Create a file name suitable for an ISO image with relaxed constraints. + * Create a file name suitable for an ISO image with level > 1 and + * with relaxed constraints. * * @param len * Max len for the name, without taken the "." into account. @@ -915,6 +978,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot) /* Convert up to lnname characters of the filename. */ for (i = 0; i < lnname; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= src[i]; if (relaxed == 2) { /* all chars are allowed */ @@ -935,6 +1001,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot) dest[pos++] = '_'; } } + +#else /* Libisofs_old_ecma119_nameS */ + + dest[pos++] = map_fileid_char(src[i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } if (lnext > 0 || forcedot) { dest[pos++] = '.'; @@ -942,6 +1015,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot) /* Convert up to lnext characters of the extension, if any. */ for (i = lname + 1; i < lname + 1 + lnext; i++) { + +#ifdef Libisofs_old_ecma119_nameS + char c= src[i]; if (relaxed == 2) { /* all chars are allowed */ @@ -962,6 +1038,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot) dest[pos++] = '_'; } } + +#else /* Libisofs_old_ecma119_nameS */ + + dest[pos++] = map_fileid_char(src[i], relaxed); + +#endif /* ! Libisofs_old_ecma119_nameS */ + } dest[pos] = '\0'; diff --git a/libisofs/util.h b/libisofs/util.h index 67a5741..6aee0db 100644 --- a/libisofs/util.h +++ b/libisofs/util.h @@ -93,8 +93,11 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output); * * @param src * The identifier, in ASCII encoding. + * @param relaxed + * 0 only allow d-characters, 1 allow also lowe case chars, + * 2 allow all characters */ -char *iso_1_dirid(const char *src); +char *iso_1_dirid(const char *src, int relaxed); /** * Create a level 2 directory identifier. @@ -124,10 +127,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed); * * @param src * The identifier, in ASCII encoding. + * @param relaxed + * 0 only allow d-characters, 1 allow also lowe case chars, + * 2 allow all characters * @param force_dots * If 1 then prepend empty extension by SEPARATOR1 = '.' */ -char *iso_1_fileid(const char *src, int force_dots); +char *iso_1_fileid(const char *src, int relaxed, int force_dots); /** * Create a level 2 file identifier.