@@ -3674,13 +3674,15 @@ enc_path_skip_prefix(const char *path, const char *end, bool mb_enc, rb_encoding
36743674 if (path + 2 <= end && isdirsep (path [0 ]) && isdirsep (path [1 ])) {
36753675 path += 2 ;
36763676 while (path < end && isdirsep (* path )) path ++ ;
3677- if ((path = enc_path_next (path , end , mb_enc , enc )) < end && path [0 ] && path [1 ] && !isdirsep (path [1 ]))
3677+ if ((path = enc_path_next (path , end , mb_enc , enc )) < end &&
3678+ path + 2 <= end && !isdirsep (path [1 ])) {
36783679 path = enc_path_next (path + 1 , end , mb_enc , enc );
3680+ }
36793681 return (char * )path ;
36803682 }
36813683#endif
36823684#ifdef DOSISH_DRIVE_LETTER
3683- if (has_drive_letter (path ))
3685+ if (path + 2 <= end && has_drive_letter (path ))
36843686 return (char * )(path + 2 );
36853687#endif
36863688#endif /* defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) */
@@ -4022,13 +4024,13 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
40224024 enc = rb_enc_get (fname );
40234025 BUFINIT ();
40244026
4025- if (s [0 ] == '~' && abs_mode == 0 ) { /* execute only if NOT absolute_path() */
4027+ if (s < fend && s [0 ] == '~' && abs_mode == 0 ) { /* execute only if NOT absolute_path() */
40264028 long userlen = 0 ;
4027- if (isdirsep ( s [ 1 ]) || s [1 ] == '\0' ) {
4029+ if (s + 1 == fend || isdirsep ( s [1 ]) ) {
40284030 buf = 0 ;
40294031 b = 0 ;
40304032 rb_str_set_len (result , 0 );
4031- if (* ++ s ) ++ s ;
4033+ if (++ s < fend ) ++ s ;
40324034 rb_default_home_dir (result );
40334035 }
40344036 else {
@@ -4058,8 +4060,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
40584060 }
40594061#ifdef DOSISH_DRIVE_LETTER
40604062 /* skip drive letter */
4061- else if (has_drive_letter (s )) {
4062- if (isdirsep (s [2 ])) {
4063+ else if (s + 1 < fend && has_drive_letter (s )) {
4064+ if (s + 2 < fend && isdirsep (s [2 ])) {
40634065 /* specified drive letter, and full path */
40644066 /* skip drive letter */
40654067 BUFCHECK (bdiff + 2 >= buflen );
@@ -4093,7 +4095,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
40934095 }
40944096 }
40954097#endif /* DOSISH_DRIVE_LETTER */
4096- else if (!rb_is_absolute_path (s )) {
4098+ else if (s == fend || !rb_is_absolute_path (s )) {
40974099 if (!NIL_P (dname )) {
40984100 rb_file_expand_path_internal (dname , Qnil , abs_mode , long_name , result );
40994101 rb_enc_associate (result , fs_enc_check (result , fname ));
@@ -4106,7 +4108,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
41064108 p = e ;
41074109 }
41084110#if defined DOSISH || defined __CYGWIN__
4109- if (isdirsep (* s )) {
4111+ if (s < fend && isdirsep (* s )) {
41104112 /* specified full path, but not drive letter nor UNC */
41114113 /* we need to get the drive letter or UNC share name */
41124114 p = skipprefix (buf , p , true, enc );
@@ -4118,7 +4120,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
41184120 else {
41194121 size_t len ;
41204122 b = s ;
4121- do s ++ ; while (isdirsep (* s ));
4123+ do s ++ ; while (s < fend && isdirsep (* s ));
41224124 len = s - b ;
41234125 p = buf + len ;
41244126 BUFCHECK (bdiff >= buflen );
@@ -4140,16 +4142,17 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
41404142 root = skipprefix (buf , p + 1 , true, enc );
41414143
41424144 b = s ;
4143- while (* s ) {
4145+ while (s < fend ) {
41444146 switch (* s ) {
41454147 case '.' :
41464148 if (b == s ++ ) { /* beginning of path element */
4147- switch (* s ) {
4148- case '\0' :
4149+ if (s == fend ) {
41494150 b = s ;
41504151 break ;
4152+ }
4153+ switch (* s ) {
41514154 case '.' :
4152- if (* ( s + 1 ) == '\0' || isdirsep (* (s + 1 ))) {
4155+ if (s + 1 == fend || isdirsep (* (s + 1 ))) {
41534156 /* We must go back to the parent */
41544157 char * n ;
41554158 * p = '\0' ;
@@ -4163,7 +4166,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
41634166 }
41644167#if USE_NTFS
41654168 else {
4166- do ++ s ; while (istrailinggarbage (* s ));
4169+ do ++ s ; while (s < fend && istrailinggarbage (* s ));
41674170 }
41684171#endif /* USE_NTFS */
41694172 break ;
@@ -4931,11 +4934,11 @@ enc_find_basename(const char *name, long *baselen, long *alllen, bool mb_enc, rb
49314934 root = name ;
49324935#endif
49334936
4934- while (isdirsep (* name )) {
4937+ while (name < end && isdirsep (* name )) {
49354938 name ++ ;
49364939 }
49374940
4938- if (! * name ) {
4941+ if (name == end ) {
49394942 p = name - 1 ;
49404943 f = 1 ;
49414944#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
@@ -5139,7 +5142,7 @@ rb_file_dirname_n(VALUE fname, int n)
51395142 return rb_enc_str_new ("." , 1 , enc );
51405143 }
51415144#ifdef DOSISH_DRIVE_LETTER
5142- if (has_drive_letter (name ) && isdirsep (* (name + 2 ))) {
5145+ if (name + 3 < end && has_drive_letter (name ) && isdirsep (* (name + 2 ))) {
51435146 const char * top = skiproot (name + 2 , end );
51445147 dirname = rb_enc_str_new (name , 3 , enc );
51455148 rb_str_cat (dirname , top , p - top );
@@ -5148,7 +5151,7 @@ rb_file_dirname_n(VALUE fname, int n)
51485151#endif
51495152 dirname = rb_enc_str_new (name , p - name , enc );
51505153#ifdef DOSISH_DRIVE_LETTER
5151- if (has_drive_letter ( name ) && root == name + 2 && p - name == 2 )
5154+ if (root == name + 2 && p == root && name [ 1 ] == ':' )
51525155 rb_str_cat (dirname , "." , 1 );
51535156#endif
51545157 return dirname ;
0 commit comments