0003-bash50-003.patch 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. From https://ftp.gnu.org/gnu/bash/bash-5.0-patches/bash50-003
  2. Signed-off-by: Pascal de Bruijn <p.debruijn@unilogic.nl>
  3. BASH PATCH REPORT
  4. =================
  5. Bash-Release: 5.0
  6. Patch-ID: bash50-003
  7. Bug-Reported-by: Andrew Church <achurch+bash@achurch.org>
  8. Bug-Reference-ID: <5c534aa2.04371@msgid.achurch.org>
  9. Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2019-01/msg00276.html
  10. Bug-Description:
  11. There are several incompatibilities in how bash-5.0 processes pathname
  12. expansion (globbing) of filename arguments that have backslashes in the
  13. directory portion.
  14. Patch (apply with `patch -p0'):
  15. *** ../bash-5.0-patched/lib/glob/glob_loop.c 2019-01-16 16:13:21.000000000 -0500
  16. --- b/lib/glob/glob_loop.c 2019-02-01 09:45:11.000000000 -0500
  17. ***************
  18. *** 27,34 ****
  19. register const GCHAR *p;
  20. register GCHAR c;
  21. ! int bopen;
  22. p = pattern;
  23. ! bopen = 0;
  24. while ((c = *p++) != L('\0'))
  25. --- 27,34 ----
  26. register const GCHAR *p;
  27. register GCHAR c;
  28. ! int bopen, bsquote;
  29. p = pattern;
  30. ! bopen = bsquote = 0;
  31. while ((c = *p++) != L('\0'))
  32. ***************
  33. *** 56,66 ****
  34. case L('\\'):
  35. /* Don't let the pattern end in a backslash (GMATCH returns no match
  36. ! if the pattern ends in a backslash anyway), but otherwise return 1,
  37. ! since the matching engine uses backslash as an escape character
  38. ! and it can be removed. */
  39. ! return (*p != L('\0'));
  40. }
  41. ! return 0;
  42. }
  43. --- 56,75 ----
  44. case L('\\'):
  45. /* Don't let the pattern end in a backslash (GMATCH returns no match
  46. ! if the pattern ends in a backslash anyway), but otherwise note that
  47. ! we have seen this, since the matching engine uses backslash as an
  48. ! escape character and it can be removed. We return 2 later if we
  49. ! have seen only backslash-escaped characters, so interested callers
  50. ! know they can shortcut and just dequote the pathname. */
  51. ! if (*p != L('\0'))
  52. ! {
  53. ! p++;
  54. ! bsquote = 1;
  55. ! continue;
  56. ! }
  57. ! else /* (*p == L('\0')) */
  58. ! return 0;
  59. }
  60. ! return bsquote ? 2 : 0;
  61. }
  62. *** ../bash-5.0-patched/lib/glob/glob.h 2013-10-28 14:46:12.000000000 -0400
  63. --- b/lib/glob/glob.h 2019-03-07 11:06:47.000000000 -0500
  64. ***************
  65. *** 31,34 ****
  66. --- 31,35 ----
  67. #define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */
  68. #define GX_GLOBSTAR 0x400 /* turn on special handling of ** */
  69. + #define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */
  70. extern int glob_pattern_p __P((const char *));
  71. *** ../bash-5.0-patched/lib/glob/glob.c 2018-09-20 10:53:23.000000000 -0400
  72. --- b/lib/glob/glob.c 2019-03-07 14:23:43.000000000 -0500
  73. ***************
  74. *** 1062,1066 ****
  75. unsigned int directory_len;
  76. int free_dirname; /* flag */
  77. ! int dflags;
  78. result = (char **) malloc (sizeof (char *));
  79. --- 1078,1082 ----
  80. unsigned int directory_len;
  81. int free_dirname; /* flag */
  82. ! int dflags, hasglob;
  83. result = (char **) malloc (sizeof (char *));
  84. ***************
  85. *** 1111,1117 ****
  86. }
  87. /* If directory_name contains globbing characters, then we
  88. ! have to expand the previous levels. Just recurse. */
  89. ! if (directory_len > 0 && glob_pattern_p (directory_name))
  90. {
  91. char **directories, *d, *p;
  92. --- 1127,1136 ----
  93. }
  94. + hasglob = 0;
  95. /* If directory_name contains globbing characters, then we
  96. ! have to expand the previous levels. Just recurse.
  97. ! If glob_pattern_p returns != [0,1] we have a pattern that has backslash
  98. ! quotes but no unquoted glob pattern characters. We dequote it below. */
  99. ! if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1)
  100. {
  101. char **directories, *d, *p;
  102. ***************
  103. *** 1176,1180 ****
  104. d[directory_len - 1] = '\0';
  105. ! directories = glob_filename (d, dflags);
  106. if (free_dirname)
  107. --- 1195,1199 ----
  108. d[directory_len - 1] = '\0';
  109. ! directories = glob_filename (d, dflags|GX_RECURSE);
  110. if (free_dirname)
  111. ***************
  112. *** 1333,1336 ****
  113. --- 1352,1369 ----
  114. return (NULL);
  115. }
  116. + /* If we have a directory name with quoted characters, and we are
  117. + being called recursively to glob the directory portion of a pathname,
  118. + we need to dequote the directory name before returning it so the
  119. + caller can read the directory */
  120. + if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0)
  121. + {
  122. + dequote_pathname (directory_name);
  123. + directory_len = strlen (directory_name);
  124. + }
  125. +
  126. + /* We could check whether or not the dequoted directory_name is a
  127. + directory and return it here, returning the original directory_name
  128. + if not, but we don't do that yet. I'm not sure it matters. */
  129. +
  130. /* Handle GX_MARKDIRS here. */
  131. result[0] = (char *) malloc (directory_len + 1);
  132. *** ../bash-5.0-patched/pathexp.c 2018-04-29 17:44:48.000000000 -0400
  133. --- b/pathexp.c 2019-01-31 20:19:41.000000000 -0500
  134. ***************
  135. *** 66,74 ****
  136. register int c;
  137. char *send;
  138. ! int open;
  139. DECLARE_MBSTATE;
  140. ! open = 0;
  141. send = string + strlen (string);
  142. --- 66,74 ----
  143. register int c;
  144. char *send;
  145. ! int open, bsquote;
  146. DECLARE_MBSTATE;
  147. ! open = bsquote = 0;
  148. send = string + strlen (string);
  149. ***************
  150. *** 101,105 ****
  151. globbing. */
  152. case '\\':
  153. ! return (*string != 0);
  154. case CTLESC:
  155. --- 101,112 ----
  156. globbing. */
  157. case '\\':
  158. ! if (*string != '\0' && *string != '/')
  159. ! {
  160. ! bsquote = 1;
  161. ! string++;
  162. ! continue;
  163. ! }
  164. ! else if (*string == 0)
  165. ! return (0);
  166. case CTLESC:
  167. ***************
  168. *** 118,122 ****
  169. #endif
  170. }
  171. ! return (0);
  172. }
  173. --- 125,130 ----
  174. #endif
  175. }
  176. !
  177. ! return (bsquote ? 2 : 0);
  178. }
  179. *** ../bash-5.0-patched/bashline.c 2019-01-16 16:13:21.000000000 -0500
  180. --- b/bashline.c 2019-02-22 09:29:08.000000000 -0500
  181. ***************
  182. *** 3753,3757 ****
  183. case '\\':
  184. ! if (*string == 0)
  185. return (0);
  186. }
  187. --- 3766,3770 ----
  188. case '\\':
  189. ! if (*string++ == 0)
  190. return (0);
  191. }
  192. *** ../bash-5.0/patchlevel.h 2016-06-22 14:51:03.000000000 -0400
  193. --- b/patchlevel.h 2016-10-01 11:01:28.000000000 -0400
  194. ***************
  195. *** 26,30 ****
  196. looks for to find the patch level (for the sccs version string). */
  197. ! #define PATCHLEVEL 2
  198. #endif /* _PATCHLEVEL_H_ */
  199. --- 26,30 ----
  200. looks for to find the patch level (for the sccs version string). */
  201. ! #define PATCHLEVEL 3
  202. #endif /* _PATCHLEVEL_H_ */