dgaudet 98/02/18 02:01:18
Modified: htdocs/manual upgrading_to_1_3.html
htdocs/manual/mod core.html
src CHANGES
src/include http_config.h
src/main http_core.c http_request.c
Log:
Fix various parsing bugs with <Dir/Loc/Files> sections. Improve the
error messages generated. Introduced cmd->end_token to make it easier
to do nested sections with proper error reporting. (Note that it can't
be used for <IfModule> or <Limit> unfortunately.)
PR#379: <Files> is not allowed within <Location> because it has no effect.
PR#1817: Change <Files> to work with basenames only. This fixes both
the bug introduced by the wildcarding change (* doesn't match /) and
bugs such as <Files a*b> not working.
PR: 379, 1817
Revision Changes Path
1.13 +6 -0 apache-1.3/htdocs/manual/upgrading_to_1_3.html
Index: upgrading_to_1_3.html
===================================================================
RCS file: /export/home/cvs/apache-1.3/htdocs/manual/upgrading_to_1_3.html,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- upgrading_to_1_3.html 1998/02/05 20:04:16 1.12
+++ upgrading_to_1_3.html 1998/02/18 10:00:57 1.13
@@ -125,6 +125,12 @@
messages. After that all errors are logged in the error_log.
This makes it more convenient to start Apache via rsh, ssh,
or crontabs.
+
+ <li><Files> sections previously could take a full pathname, and
+ were matched against the full pathnames. This had some
+ inconsistancies, and was removed. To emulate this older behaviour
+ use a <Files> section nested inside a <Directory>
+ section.
</UL>
1.101 +10 -7 apache-1.3/htdocs/manual/mod/core.html
Index: core.html
===================================================================
RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/core.html,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- core.html 1998/02/15 00:18:14 1.100
+++ core.html 1998/02/18 10:01:01 1.101
@@ -811,12 +811,17 @@
filename. It is comparable to the <A
HREF="#directory"><Directory></A> directive and
<A HREF="#location"><Location></A> directives. It
-should be matched with a </Files> directive. Directives that
-apply to the filename given should be listed
-within. <CODE><Files></CODE> sections are processed in the
+should be matched with a </Files> directive. The
+directives given within this section will be applied to any
+object with a basename (last component of filename) matching
+the specified filename.
+<CODE><Files></CODE> sections are processed in the
order they appear in the configuration file, after the
<Directory> sections and <CODE>.htaccess</CODE> files are
-read, but before <Location> sections.</P>
+read, but before <Location> sections. Note that
+<Files> can be nested inside <Directory>
+sections to restrict the portion of the filesystem they
+apply to.</P>
<P>The <EM>filename</EM> argument should include a filename, or a
wild-card string, where `?' matches any single character, and `*' matches any
@@ -837,9 +842,7 @@
HREF="#location"><CODE><Location></CODE></A> sections,
<CODE><Files></CODE> sections can be used inside .htaccess
files. This allows users to control access to their own files, at a
-file-by-file level. When used in an .htaccess file, if the
-<EM>filename</EM> does not begin with a <CODE>/</CODE> character,
-the directory being applied will be prefixed automatically.
+file-by-file level.
<P>
1.636 +14 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.635
retrieving revision 1.636
diff -u -r1.635 -r1.636
--- CHANGES 1998/02/18 08:55:30 1.635
+++ CHANGES 1998/02/18 10:01:05 1.636
@@ -1,5 +1,19 @@
Changes with Apache 1.3b6
+ *) Previously Apache would permit </Files> to end <FilesMatch> (and
+ similary for Location and Directory), now this is diagnosed as an
+ error. Improve error messages for mismatched sections (<Files>,
+ <FilesMatch>, <Directory>, <DirectoryMatch>, ...). [Dean Gaudet]
+
+ *) <Files> is not permitted within <Location> (because of the
+ semantic ordering). [Dean Gaudet] PR#379
+
+ *) <Files> with wildcards was broken by the change in wildcard
+ semantics (* does not match /). To fix this, <Files> now
+ apply only to the basename of the request filename. This
+ fixes some other inconsistencies in <Files> semantics
+ (such as <Files a*b> not working). [Dean Gaudet] PR#1817
+
*) Removed bogus "dist.tar" target from Makefile.tmpl and make sure
backup files are removed on "clean" target [Ralf S. Engelschall]
1.67 +3 -2 apache-1.3/src/include/http_config.h
Index: http_config.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/include/http_config.h,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- http_config.h 1998/02/18 08:35:55 1.66
+++ http_config.h 1998/02/18 10:01:10 1.67
@@ -80,7 +80,7 @@
};
typedef struct command_struct {
- char *name; /* Name of this command */
+ const char *name; /* Name of this command */
const char *(*func) (); /* Function invoked */
void *cmd_data; /* Extra data, for functions which
* implement multiple commands...
@@ -90,7 +90,7 @@
*/
enum cmd_how args_how; /* What the command expects as arguments */
- char *errmsg; /* 'usage' message, in case of syntax errors */
+ const char *errmsg; /* 'usage' message, in case of syntax
errors */
} command_rec;
/* The allowed locations for a configuration directive are the union of
@@ -156,6 +156,7 @@
* or being called in a dir context (path !=
NULL).
*/
const command_rec *cmd; /* configuration command */
+ const char *end_token; /* end token required to end a nested section */
} cmd_parms;
/* This structure records the existence of handlers in a module... */
1.159 +80 -62 apache-1.3/src/main/http_core.c
Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.158
retrieving revision 1.159
diff -u -r1.158 -r1.159
--- http_core.c 1998/02/12 02:18:41 1.158
+++ http_core.c 1998/02/18 10:01:13 1.159
@@ -643,10 +643,20 @@
* commands, but most of the old srm.conf is in the the modules.
*/
+static const char end_directory_section[] = "</Directory>";
+static const char end_directorymatch_section[] = "</DirectoryMatch>";
+static const char end_location_section[] = "</Location>";
+static const char end_locationmatch_section[] = "</LocationMatch>";
+static const char end_files_section[] = "</Files>";
+static const char end_filesmatch_section[] = "</FilesMatch>";
+static const char end_virtualhost_section[] = "</VirtualHost>";
+static const char end_ifmodule_section[] = "</IfModule>";
+
/* check_cmd_context(): Forbidden in: */
#define NOT_IN_VIRTUALHOST 0x01U /* <Virtualhost> */
#define NOT_IN_LIMIT 0x02U /* <Limit> */
#define NOT_IN_DIR_LOC_FILE 0x04U /* <Directory>/<Location>/<Files>*/
+#define NOT_IN_LOC 0x08U /* <Location> */
#define GLOBAL_ONLY
(NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE)
@@ -666,6 +676,11 @@
if ((forbidden & NOT_IN_DIR_LOC_FILE) && cmd->path != NULL)
return pstrcat(cmd->pool, cmd->cmd->name, gt,
" cannot occur within <Directory/Location/Files>
section", NULL);
+
+ if ((forbidden & NOT_IN_LOC) && (cmd->end_token == end_location_section
+ || cmd->end_token == end_locationmatch_section))
+ return pstrcat(cmd->pool, cmd->cmd->name, gt,
+ " cannot occur within <Location> section", NULL);
return NULL;
}
@@ -908,11 +923,11 @@
char rply[100];
if (nest < 2)
- ap_snprintf(rply, sizeof rply, "Missing </%s> directive at end-of-file",
- &cmd->cmd->name[1]);
+ ap_snprintf(rply, sizeof rply, "Missing %s directive at end-of-file",
+ cmd->end_token);
else
- ap_snprintf(rply, sizeof rply, "%d missing </%s> directives at
end-of-file",
- nest, &cmd->cmd->name[1]);
+ ap_snprintf(rply, sizeof rply, "%d missing %s directives at
end-of-file",
+ nest, cmd->end_token);
return pstrdup(cmd->pool, rply);
}
@@ -927,10 +942,17 @@
#define USE_ICASE 0
#endif
-static const char end_dir_magic[] = "</Directory> outside of any <Directory>
section";
-
-const char *end_dirsection (cmd_parms *cmd, void *dummy) {
- return end_dir_magic;
+static const char *end_nested_section(cmd_parms *cmd, void *dummy)
+{
+ if (cmd->end_token == NULL) {
+ return pstrcat(cmd->pool, cmd->cmd->name,
+ " without matching <", cmd->cmd->name + 2, " section", NULL);
+ }
+ if (cmd->cmd->name != cmd->end_token) {
+ return pstrcat(cmd->pool, "Expected ", cmd->end_token, " but saw ",
+ cmd->cmd->name, NULL);
+ }
+ return cmd->end_token;
}
const char *dirsection (cmd_parms *cmd, void *dummy, const char *arg)
@@ -942,6 +964,7 @@
core_dir_config *conf;
void *new_dir_conf = create_per_dir_config (cmd->pool);
regex_t *r = NULL;
+ const char *old_end_token;
const char *err = check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
if (err != NULL) return err;
@@ -967,10 +990,14 @@
cmd->path = os_canonical_filename(cmd->pool, cmd->path);
}
+ old_end_token = cmd->end_token;
+ cmd->end_token = cmd->info ? end_directorymatch_section :
end_directory_section;
errmsg = srm_command_loop (cmd, new_dir_conf);
- if (errmsg == NULL)
- return missing_endsection(cmd, 1);
- else if (errmsg != end_dir_magic)
+ if (errmsg == NULL) {
+ errmsg = missing_endsection(cmd, 1);
+ }
+ cmd->end_token = old_end_token;
+ if (errmsg != (cmd->info ? end_directorymatch_section :
end_directory_section))
return errmsg;
conf = (core_dir_config *)get_module_config(new_dir_conf, &core_module);
@@ -988,12 +1015,6 @@
return NULL;
}
-static const char end_url_magic[] = "</Location> outside of any <Location>
section";
-
-const char *end_urlsection (cmd_parms *cmd, void *dummy) {
- return end_url_magic;
-}
-
const char *urlsection (cmd_parms *cmd, void *dummy, const char *arg)
{
const char *errmsg;
@@ -1002,6 +1023,7 @@
char *old_path = cmd->path;
core_dir_config *conf;
regex_t *r = NULL;
+ const char *old_end_token;
void *new_url_conf = create_per_dir_config (cmd->pool);
@@ -1021,10 +1043,14 @@
r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
}
+ old_end_token = cmd->end_token;
+ cmd->end_token = cmd->info ? end_locationmatch_section :
end_location_section;
errmsg = srm_command_loop (cmd, new_url_conf);
- if (errmsg == NULL)
- return missing_endsection(cmd, 1);
- else if (errmsg != end_url_magic)
+ if (errmsg == NULL) {
+ errmsg = missing_endsection(cmd, 1);
+ }
+ cmd->end_token = old_end_token;
+ if (errmsg != (cmd->info ? end_locationmatch_section :
end_location_section))
return errmsg;
conf = (core_dir_config *)get_module_config(new_url_conf, &core_module);
@@ -1044,12 +1070,6 @@
return NULL;
}
-static char *end_file_magic = "</Files> outside of any <Files> section";
-
-const char *end_filesection (cmd_parms *cmd, void *dummy) {
- return end_file_magic;
-}
-
const char *filesection (cmd_parms *cmd, core_dir_config *c, const char *arg)
{
const char *errmsg;
@@ -1058,53 +1078,49 @@
char *old_path = cmd->path;
core_dir_config *conf;
regex_t *r = NULL;
+ const char *old_end_token;
void *new_file_conf = create_per_dir_config (cmd->pool);
- const char *err = check_cmd_context(cmd, NOT_IN_LIMIT);
+ const char *err = check_cmd_context(cmd, NOT_IN_LIMIT | NOT_IN_LOC);
if (err != NULL) return err;
if (endp) *endp = '\0';
- if (cmd->limited != -1) return "Can't have <Files> within <Limit>";
-
cmd->path = getword_conf (cmd->pool, &arg);
/* Only if not an .htaccess file */
- if (cmd->path)
+ if (!old_path)
cmd->override = OR_ALL|ACCESS_CONF;
if (cmd->info) { /* <FilesMatch> */
- if (old_path && cmd->path[0] != '/' && cmd->path[0] != '^')
- cmd->path = pstrcat(cmd->pool, "^", old_path, cmd->path, NULL);
r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
}
else if (!strcmp(cmd->path, "~")) {
cmd->path = getword_conf (cmd->pool, &arg);
- if (old_path && cmd->path[0] != '/' && cmd->path[0] != '^')
- cmd->path = pstrcat(cmd->pool, "^", old_path, cmd->path, NULL);
r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE);
}
else {
- if (old_path && cmd->path[0] != '/')
- cmd->path = pstrcat(cmd->pool, old_path, cmd->path, NULL);
-
/* Ensure that the pathname is canonical */
cmd->path = os_canonical_filename(cmd->pool, cmd->path);
}
+ old_end_token = cmd->end_token;
+ cmd->end_token = cmd->info ? end_filesmatch_section : end_files_section;
errmsg = srm_command_loop (cmd, new_file_conf);
- if (errmsg == NULL)
- return missing_endsection(cmd, 1);
- else if (errmsg != end_file_magic)
+ if (errmsg == NULL) {
+ errmsg = missing_endsection(cmd, 1);
+ }
+ cmd->end_token = old_end_token;
+ if (errmsg != (cmd->info ? end_filesmatch_section : end_files_section))
return errmsg;
conf = (core_dir_config *)get_module_config(new_file_conf, &core_module);
- conf->d = pstrdup(cmd->pool, cmd->path);
- conf->d_is_fnmatch = is_fnmatch( conf->d ) != 0;
+ conf->d = cmd->path;
+ conf->d_is_fnmatch = is_fnmatch(conf->d) != 0;
conf->r = r;
add_file_conf (c, new_file_conf);
-
+
if (*arg != '\0')
return pstrcat (cmd->pool, "Multiple <", (cmd->info) ? "FilesMatch" :
"Files",
"> arguments not (yet) supported.", NULL);
@@ -1142,24 +1158,22 @@
nest--;
}
- return (nest == 0) ? NULL : missing_endsection(cmd, nest);
+ if (nest) {
+ cmd->end_token = end_ifmodule_section;
+ return missing_endsection(cmd, nest);
+ }
+ return NULL;
}
/* httpd.conf commands... beginning with the <VirtualHost> business */
-const char end_virthost_magic[] = "</Virtualhost> out of place";
-
-const char *end_virtualhost_section (cmd_parms *cmd, void *dummy)
-{
- return end_virthost_magic;
-}
-
const char *virtualhost_section (cmd_parms *cmd, void *dummy, char *arg)
{
server_rec *main_server = cmd->server, *s;
const char *errmsg;
char *endp = strrchr (arg, '>');
pool *p = cmd->pool, *ptemp = cmd->temp_pool;
+ const char *old_end_token;
const char *err = check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) return err;
@@ -1181,9 +1195,15 @@
s->next = main_server->next;
main_server->next = s;
+ old_end_token = cmd->end_token;
+ cmd->end_token = end_virtualhost_section;
cmd->server = s;
errmsg = srm_command_loop (cmd, s->lookup_defaults);
cmd->server = main_server;
+ if (errmsg == NULL) {
+ errmsg = missing_endsection(cmd, 1);
+ }
+ cmd->end_token = old_end_token;
if (s->srm_confname)
process_resource_config (s, s->srm_confname, p, ptemp);
@@ -1191,9 +1211,7 @@
if (s->access_confname)
process_resource_config (s, s->access_confname, p, ptemp);
- if (errmsg == NULL)
- return missing_endsection(cmd, 1);
- else if (errmsg == end_virthost_magic)
+ if (errmsg == end_virtualhost_section)
return NULL;
return errmsg;
}
@@ -1779,23 +1797,23 @@
/* Old access config file commands */
{ "<Directory", dirsection, NULL, RSRC_CONF, RAW_ARGS, "Container for
directives affecting resources located in the specified directories" },
-{ "</Directory>", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, "Marks end of
<Directory>" },
+{ end_directory_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
"Marks end of <Directory>" },
{ "<Location", urlsection, NULL, RSRC_CONF, RAW_ARGS, "Container for
directives affecting resources accessed through the specified URL paths" },
-{ "</Location>", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, "Marks end of
<Location>" },
+{ end_location_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
"Marks end of <Location>" },
{ "<VirtualHost", virtualhost_section, NULL, RSRC_CONF, RAW_ARGS, "Container
to map directives to a particular virtual host, takes one or more host
addresses" },
-{ "</VirtualHost>", end_virtualhost_section, NULL, RSRC_CONF, NO_ARGS,
"Marks end of <Directory>" },
+{ end_virtualhost_section, end_nested_section, NULL, RSRC_CONF, NO_ARGS,
"Marks end of <VirtualHost>" },
{ "<Files", filesection, NULL, OR_ALL, RAW_ARGS, "Container for directives
affecting files matching specified patterns" },
-{ "</Files>", end_filesection, NULL, OR_ALL, NO_ARGS, "Marks end of <Files>"
},
+{ end_files_section, end_nested_section, NULL, OR_ALL, NO_ARGS, "Marks end
of <Files>" },
{ "<Limit", limit_section, NULL, OR_ALL, RAW_ARGS, "Container for
authentication directives when accessed using specified HTTP methods" },
{ "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS, "Marks end of
<Limit>" },
{ "<IfModule", start_ifmod, NULL, OR_ALL, RAW_ARGS, "Container for
directives based on existance of specified modules" },
-{ "</IfModule>", end_ifmod, NULL, OR_ALL, NO_ARGS, "Marks end of <IfModule>"
},
+{ end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS, "Marks end of
<IfModule>" },
{ "<DirectoryMatch", dirsection, (void*)1, RSRC_CONF, RAW_ARGS, "Container
for directives affecting resources located in the specified directories" },
-{ "</DirectoryMatch>", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, "Marks
end of <DirectoryMatch>" },
+{ end_directorymatch_section, end_nested_section, NULL, ACCESS_CONF,
NO_ARGS, "Marks end of <DirectoryMatch>" },
{ "<LocationMatch", urlsection, (void*)1, RSRC_CONF, RAW_ARGS, "Container
for directives affecting resources accessed through the specified URL paths" },
-{ "</LocationMatch>", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, "Marks end
of <LocationMatch>" },
+{ end_locationmatch_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
"Marks end of <LocationMatch>" },
{ "<FilesMatch", filesection, (void*)1, OR_ALL, RAW_ARGS, "Container for
directives affecting files matching specified patterns" },
-{ "</FilesMatch>", end_filesection, NULL, OR_ALL, NO_ARGS, "Marks end of
<FilesMatch>" },
+{ end_filesmatch_section, end_nested_section, NULL, OR_ALL, NO_ARGS, "Marks
end of <FilesMatch>" },
{ "AuthType", set_string_slot, (void*)XtOffsetOf(core_dir_config, auth_type),
OR_AUTHCFG, TAKE1, "An HTTP authorization type (e.g., \"Basic\")" },
{ "AuthName", set_authname, NULL, OR_AUTHCFG, TAKE1,
1.107 +11 -6 apache-1.3/src/main/http_request.c
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/http_request.c,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -r1.106 -r1.107
--- http_request.c 1998/02/08 18:16:03 1.106
+++ http_request.c 1998/02/18 10:01:14 1.107
@@ -561,10 +561,16 @@
void *per_dir_defaults = r->per_dir_config;
void **file = (void **) conf->sec->elts;
int len, num_files = conf->sec->nelts;
- char *test_file = pstrdup(r->pool, r->filename);
+ char *test_file;
- /* Collapse multiple slashes */
- no2slash(test_file);
+ /* get the basename */
+ test_file = strrchr(r->filename, '/');
+ if (test_file == NULL) {
+ test_file = r->filename;
+ }
+ else {
+ ++test_file;
+ }
/* Go through the file entries, and check for matches. */
@@ -598,10 +604,9 @@
this_conf = entry_config;
}
}
- else if (!strncmp(test_file, entry_file, len) &&
- (entry_file[len - 1] == '/' ||
- test_file[len] == '/' || test_file[len] == '\0'))
+ else if (!strcmp(test_file, entry_file)) {
this_conf = entry_config;
+ }
if (this_conf)
per_dir_defaults = merge_per_dir_configs(r->pool,