~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/docs/canonical_filenames.html

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<HTML>
 
2
<HEAD><TITLE>APR Canonical Filenames</TITLE></HEAD>
 
3
<BODY>
 
4
<h1>APR Canonical Filename</h1>
 
5
 
 
6
<h2>Requirements</h2>
 
7
 
 
8
<p>APR porters need to address the underlying discrepancies between
 
9
file systems.  To achieve a reasonable degree of security, the
 
10
program depending upon APR needs to know that two paths may be
 
11
compared, and that a mismatch is guarenteed to reflect that the
 
12
two paths do not return the same resource</p>.
 
13
 
 
14
<p>The first discrepancy is in volume roots.  Unix and pure deriviates
 
15
have only one root path, "/".  Win32 and OS2 share root paths of
 
16
the form "D:/", D: is the volume designation.  However, this can
 
17
be specified as "//./D:/" as well, indicating D: volume of the 
 
18
'this' machine.  Win32 and OS2 also may employ a UNC root path,
 
19
of the form "//server/share/" where share is a share-point of the
 
20
specified network server.  Finally, NetWare root paths are of the
 
21
form "server/volume:/", or the simpler "volume:/" syntax for 'this'
 
22
machine.  All these non-Unix file systems accept volume:path,
 
23
without a slash following the colon, as a path relative to the
 
24
current working directory, which APR will treat as ambigious, that
 
25
is, neither an absolute nor a relative path per se.</p>
 
26
 
 
27
<p>The second discrepancy is in the meaning of the 'this' directory.
 
28
In general, 'this' must be eliminated from the path where it occurs.
 
29
The syntax "path/./" and "path/" are both aliases to path.  However,
 
30
this isn't file system independent, since the double slash "//" has
 
31
a special meaning on OS2 and Win32 at the start of the path name,
 
32
and is invalid on those platforms before the "//server/share/" UNC
 
33
root path is completed.  Finally, as noted above, "//./volume/" is
 
34
legal root syntax on WinNT, and perhaps others.</p>
 
35
 
 
36
<p>The third discrepancy is in the context of the 'parent' directory.
 
37
When "parent/path/.." occurs, the path must be unwound to "parent".
 
38
It's also critical to simply truncate leading "/../" paths to "/",
 
39
since the parent of the root is root.  This gets tricky on the
 
40
Win32 and OS2 platforms, since the ".." element is invalid before
 
41
the "//server/share/" is complete, and the "//server/share/../"
 
42
seqence is the complete UNC root "//server/share/".  In relative
 
43
paths, leading ".." elements are significant, until they are merged
 
44
with an absolute path.  The relative form must only retain the ".."
 
45
segments as leading segments, to be resolved once merged to another
 
46
relative or an absolute path.</p>
 
47
 
 
48
<p>The fourth discrepancy occurs with acceptance of alternate character
 
49
codes for the same element.  Path seperators are not retained within
 
50
the APR canonical forms.  The OS filesystem and APR (slashed) forms
 
51
can both be returned as strings, to be used in the proper context.
 
52
Unix, Win32 and Netware all accept slashes and backslashes as the
 
53
same path seperator symbol, although unix strictly accepts slashes.
 
54
While the APR form of the name strictly uses slashes, always consider
 
55
that there could be a platform that actually accepts slashes as a
 
56
character within a segment name.</p>
 
57
 
 
58
<p>The fifth and worst discrepancy plauges Win32, OS2, Netware, and some
 
59
filesystems mounted in Unix.  Case insensitivity can permit the same
 
60
file to slip through in both it's proper case and alternate cases.
 
61
Simply changing the case is insufficient for any character set beyond
 
62
ASCII, since various dilectic forms of characters suffer from one to
 
63
many or many to one translations.  An example would be u-umlaut, which
 
64
might be accepted as a single character u-umlaut, a two character
 
65
sequence u and the zero-width umlaut, the upper case form of the same,
 
66
or perhaps even a captial U alone.  This can be handled in different
 
67
ways depending on the purposes of the APR based program, but the one
 
68
requirement is that the path must be absolute in order to resolve these
 
69
ambiguities.  Methods employed include comparison of device and inode
 
70
file uniqifiers, which is a fairly fast operation, or quering the OS
 
71
for the true form of the name, which can be much slower.  Only the
 
72
acknowledgement of the file names by the OS can validate the equality
 
73
of two different cases of the same filename.</p>
 
74
 
 
75
<p>The sixth discrepancy, illegal or insignificant characters, is especially 
 
76
significant in non-unix file systems.  Trailing periods are accepted
 
77
but never stored, therefore trailing periods must be ignored for any
 
78
form of comparison.  And all OS's have certain expectations of what
 
79
characters are illegal (or undesireable due to confusion.)</p>
 
80
 
 
81
<p>A final warning, canonical functions don't transform or resolve case
 
82
or character ambiguity issues until they are resolved into an absolute
 
83
path.  The relative canonical path, while useful, while useful for URL
 
84
or similar identifiers, cannot be used for testing or comparison of file 
 
85
system objects.</p>
 
86
 
 
87
<hr>
 
88
 
 
89
<h2>Canonical API</h2>
 
90
 
 
91
Functions to manipulate the apr_canon_file_t (an opaque type) include:
 
92
 
 
93
<ul>
 
94
<li>Create canon_file_t (from char* path and canon_file_t parent path)
 
95
<li>Merged canon_file_t (from path and parent, both canon_file_t)
 
96
<li>Get char* path of all or some segments
 
97
<li>Get path flags of IsRelative, IsVirtualRoot, and IsAbsolute
 
98
<li>Compare two canon_file_t structures for file equality
 
99
</ul>
 
100
 
 
101
<p>The path is corrected to the file system case only if is in absolute 
 
102
form.  The apr_canon_file_t should be preserved as long as possible and 
 
103
used as the parent to create child entries to reduce the number of expensive 
 
104
stat and case canonicalization calls to the OS.</p>
 
105
 
 
106
<p>The comparison operation provides that the APR can postpone correction
 
107
of case by simply relying upon the device and inode for equivilance.  The
 
108
stat implementation provides that two files are the same, while their
 
109
strings are not equivilant, and eliminates the need for the operating
 
110
system to return the proper form of the name.</p>
 
111
 
 
112
<p>In any case, returning the char* path, with a flag to request the proper
 
113
case, forces the OS calls to resolve the true names of each segment.  Where
 
114
there is a penality for this operation and the stat device and inode test
 
115
is faster, case correction is postponed until the char* result is requested.
 
116
On platforms that identify the inode, device, or proper name interchangably
 
117
with no penalities, this may occur when the name is initially processed.</p>
 
118
 
 
119
<hr>
 
120
 
 
121
<h2>Unix Example</h2>
 
122
 
 
123
<p>First the simplest case:</p>
 
124
 
 
125
<pre>
 
126
Parse Canonical Name 
 
127
accepts parent path as canonical_t
 
128
        this path as string
 
129
 
 
130
Split this path Segments on '/'
 
131
 
 
132
For each of this path Segments
 
133
  If first Segment
 
134
    If this Segment is Empty ([nothing]/)
 
135
      Append this Root Segment (don't merge)
 
136
      Continue to next Segment
 
137
    Else is relative
 
138
      Append parent Segments (to merge)
 
139
      Continue with this Segment
 
140
  If Segment is '.' or empty (2 slashes)
 
141
    Discard this Segment
 
142
    Continue with next Segment
 
143
  If Segment is '..'
 
144
    If no previous Segment or previous Segment is '..'
 
145
      Append this Segment
 
146
      Continue with next Segment
 
147
    If previous Segment and previous is not Root Segment
 
148
      Discard previous Segment
 
149
    Discard this Segment
 
150
    Continue with next Segment
 
151
  Append this Relative Segment
 
152
  Continue with next Segment        
 
153
</pre>
 
154
 
 
155
</BODY>
 
156
</HTML>
 
 
b'\\ No newline at end of file'