diff --git a/libisofs/builder.c b/libisofs/builder.c index 15a500d..541d26f 100644 --- a/libisofs/builder.c +++ b/libisofs/builder.c @@ -75,6 +75,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image, iso_file_source_ref(src); name = iso_file_source_get_name(src); + if (strlen(name) > LIBISOFS_NODE_NAME_MAX) + name[LIBISOFS_NODE_NAME_MAX] = 0; ret = iso_node_new_file(name, stream, &node); if (ret < 0) { iso_stream_unref(stream); @@ -122,6 +124,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image, } name = iso_file_source_get_name(src); + if (strlen(name) > LIBISOFS_NODE_NAME_MAX) + name[LIBISOFS_NODE_NAME_MAX] = 0; fs = iso_file_source_get_filesystem(src); new = NULL; @@ -157,10 +161,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image, case S_IFLNK: { /* source is a symbolic link */ - char dest[PATH_MAX]; + char dest[PATH_MAX + LIBISOFS_NODE_PATH_MAX]; IsoSymlink *link; - ret = iso_file_source_readlink(src, dest, PATH_MAX); + ret = iso_file_source_readlink(src, dest, + PATH_MAX + LIBISOFS_NODE_PATH_MAX); if (ret < 0) { break; } diff --git a/libisofs/filesrc.c b/libisofs/filesrc.c index 21bbfc5..aa663cf 100644 --- a/libisofs/filesrc.c +++ b/libisofs/filesrc.c @@ -338,7 +338,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer) Ecma119Image *t; IsoFileSrc *file; IsoFileSrc **filelist; - char name[PATH_MAX]; + char name[PATH_MAX + LIBISOFS_NODE_PATH_MAX]; char buffer[BLOCK_SIZE]; off_t file_size; uint32_t nblocks; diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 8ac322e..b5258c5 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -2926,10 +2926,11 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image, case S_IFLNK: { /* source is a symbolic link */ - char dest[PATH_MAX]; + char dest[PATH_MAX + LIBISOFS_NODE_PATH_MAX]; IsoSymlink *link; - ret = iso_file_source_readlink(src, dest, PATH_MAX); + ret = iso_file_source_readlink(src, dest, + PATH_MAX + LIBISOFS_NODE_PATH_MAX); if (ret < 0) { free(name); return ret; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index ef462c6..be15023 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -6834,6 +6834,9 @@ int iso_md5_match(char first_md5[16], char second_md5[16]); /** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */ #define ISO_RR_NAME_RESERVED 0xE830FE86 +/** Rock Ridge path too long (FAILURE, HIGH, -379) */ +#define ISO_RR_PATH_TOO_LONG 0xE830FE85 + /* Internal developer note: diff --git a/libisofs/messages.c b/libisofs/messages.c index 9afa979..cc9bf74 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -459,6 +459,8 @@ const char *iso_error_to_msg(int errcode) return "Rock Ridge leaf name too long"; case ISO_RR_NAME_RESERVED: return "Reserved Rock Ridge leaf name"; + case ISO_RR_PATH_TOO_LONG: + return "Rock Ridge path too long"; default: return "Unknown error"; } diff --git a/libisofs/node.c b/libisofs/node.c index c5eb279..529fdaa 100644 --- a/libisofs/node.c +++ b/libisofs/node.c @@ -28,11 +28,6 @@ #include -#ifndef PATH_MAX -#define PATH_MAX Libisofs_default_path_maX -#endif - - struct dir_iter_data { /* points to the last visited child, to NULL before start */ @@ -1167,7 +1162,7 @@ int iso_node_is_valid_name(const char *name) /* guard against the empty string or big names... */ if (name[0] == '\0') return ISO_RR_NAME_RESERVED; - if (strlen(name) > 255) + if (strlen(name) > LIBISOFS_NODE_NAME_MAX) return ISO_RR_NAME_TOO_LONG; /* ...against "." and ".." names... */ @@ -1201,8 +1196,8 @@ int iso_node_is_valid_link_dest(const char *dest) /* guard against the empty string or big dest... */ if (dest[0] == '\0') return ISO_RR_NAME_RESERVED; - if (strlen(dest) > PATH_MAX) - return ISO_RR_NAME_TOO_LONG; + if (strlen(dest) > LIBISOFS_NODE_PATH_MAX) + return ISO_RR_PATH_TOO_LONG; /* check that all components are valid */ if (!strcmp(dest, "/")) { diff --git a/libisofs/node.h b/libisofs/node.h index 9aebbe2..5996e64 100644 --- a/libisofs/node.h +++ b/libisofs/node.h @@ -30,6 +30,29 @@ #endif +/* Maximum length of a leaf name in the libisofs node tree. This is currently + restricted by the implemented maximum length of a Rock Ridge name. + This might later become larger and may then be limited to smaller values. + + Rock Ridge specs do not impose an explicit limit on name length. + But 255 is also specified by + http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html + which says + NAME_MAX >= _XOPEN_NAME_MAX = 255 +*/ +#define LIBISOFS_NODE_NAME_MAX 255 + + +/* Maximum length of a path in the libisofs node tree. + Rock Ridge specs do not impose an explicit limit on name length. + + http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html + says + PATH_MAX >= _XOPEN_PATH_MAX = 1024 +*/ +#define LIBISOFS_NODE_PATH_MAX 1024 + + /** * The extended information is a way to attach additional information to each * IsoNode. External applications may want to use this extension system to diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 817c726..7c59185 100644 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -342,6 +342,9 @@ int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size, return ISO_OUT_OF_MEM; } + if (size > 250) + return ISO_ASSERT_FAILURE; + NM[0] = 'N'; NM[1] = 'M'; NM[2] = size + 5; @@ -973,6 +976,18 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space, *su_size += 28; } +/* <<< */ +#ifdef NIX +{ + static int min_free = 1000; + if (space - *su_size < min_free) { + min_free = space - *su_size; + fprintf(stderr, "LIBISOFS_DEBUG: minimum free SUA before NM = %d\n", + min_free); + } +} +#endif /* NIX */ + /* NM entry */ if (*su_size + 5 + namelen <= space) { /* ok, it fits in System Use Area */ @@ -982,6 +997,9 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space, if (!(flag & 1)) goto unannounced_ca; namelen = namelen - (space - *su_size - 5); + + /* >>> Need to handle lengths > 250 */; + *ce = 5 + namelen; *su_size = space; } @@ -1659,6 +1677,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type, /* * ..and the part that goes to continuation area. */ + + /* >>> Need a loop to handle lengths > 250 */; + ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen), 0, 1); if (ret < 0) { diff --git a/libisofs/stream.c b/libisofs/stream.c index f70d415..b885d4c 100644 --- a/libisofs/stream.c +++ b/libisofs/stream.c @@ -16,6 +16,7 @@ #include "stream.h" #include "fsource.h" #include "util.h" +#include "node.h" #include #include @@ -868,7 +869,8 @@ void iso_stream_get_file_name(IsoStream *stream, char *name) if (!strncmp(type, "fsrc", 4)) { FSrcStreamData *data = stream->data; char *path = iso_file_source_get_path(data->src); - strncpy(name, path, PATH_MAX); + strncpy(name, path, PATH_MAX + LIBISOFS_NODE_PATH_MAX - 1); + name[PATH_MAX + LIBISOFS_NODE_PATH_MAX - 1] = 0; free(path); } else if (!strncmp(type, "boot", 4)) { strcpy(name, "BOOT CATALOG"); diff --git a/libisofs/tree.c b/libisofs/tree.c index 46b66d3..6cb3144 100644 --- a/libisofs/tree.c +++ b/libisofs/tree.c @@ -32,11 +32,6 @@ #include -#ifndef PATH_MAX -#define PATH_MAX Libisofs_default_path_maX -#endif - - /** * Add a new directory to the iso tree. * @@ -980,15 +975,16 @@ char *iso_tree_get_node_path(IsoNode *node) if ((IsoNode*)node->parent == node) { return strdup("/"); } else { - char path[PATH_MAX]; + char path[LIBISOFS_NODE_PATH_MAX]; char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent); if (parent_path == NULL) { return NULL; } if (strlen(parent_path) == 1) { - snprintf(path, PATH_MAX, "/%s", node->name); + snprintf(path, LIBISOFS_NODE_PATH_MAX, "/%s", node->name); } else { - snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name); + snprintf(path, LIBISOFS_NODE_PATH_MAX, "%s/%s", + parent_path, node->name); } free(parent_path); return strdup(path);