1
0
mirror of https://github.com/vitalif/viewvc-4intranet synced 2019-04-16 04:14:59 +03:00

Compare commits

..

53 Commits

Author SHA1 Message Date
cmpilato
2412b3fbb0 Tag the 1.0.13 final release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/tags/1.0.13@2800 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-10-24 17:21:31 +00:00
cmpilato
be62f7e5dd Peg the 1.0.13 release date for today.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2799 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-10-24 17:20:05 +00:00
cmpilato
f353edafc4 Bump copyright years on all source files.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2798 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-10-24 17:18:35 +00:00
cmpilato
244b24e7c1 Merge from trunk r2792, whose log message read like so:
Fix issue #515 ("XSS bug in diff view (CVE-2012-4533)").
   
   * lib/viewvc.py
     (DiffSource._get_row): Pass the "extra" line information through the
       formatter code so that, at a minimum, it's HTML-escaped.
   
   Patch by: Nicolás Alvarez <nicolas.alvarez{__AT__}gmail.com>

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2794 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-10-24 13:34:32 +00:00
cmpilato
cd8a53c4ca Bump copyright years. (Merged /trunk:r2524,2716)
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2718 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-23 16:45:25 +00:00
cmpilato
68c5b47282 Merge from trunk r2671, whose log message went a little something like this:
Fix issue #499 ("svndbadmin fails on deleted files").
   
   * bin/svndbadmin
     (SvnRev.__init__): Update the logic used to calculate change types
       and diff objects to no longer assume that deleted paths have None
       for their change.path.  (Subversion's 1.7 bindings always populate
       change.path.)

Some conflict resolution was required, as the 1.0.x line still throws around
pool parameters in the Subversion bindings.

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2673 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-14 20:19:50 +00:00
cmpilato
b6ce909ac1 Merge from trunk r2609 (fixed pointer to Subversion website).
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2611 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-04 15:00:24 +00:00
cmpilato
53b96700ef Merge from trunk r2547, whose log message read like so:
Try to make some sense of the various CVSdb-related limitation
   mechanisms, namely by removing the largely redundant "global" limit
   and allowing the per-query row limit (which already exist, too) to do
   its work.
   
   While here, remove a poorly conceived (but thankfully unhighlighted)
   mechanism for overriding the administrative limit on database rows
   which was accessible via URL CGI params.
   
   * lib/viewvc.py
     (_legal_params): Remove 'limit' as a legal parameter.
     (view_query): No longer allow an undocumented URL parameter to
       override the admin-declared SQL row limit.  That should have never
       been allowed!
   
   * lib/cvsdb.py
     (CheckinDatabase.__init__): Remove 'row_limit' parameter and
       associated self._row_limit member.
     (CheckinDatabase.CreateSQLQueryString): No longer fuss with
       self._row_limit.  Let the individual query carry the row limit.
     (ConnectDatabase): Update call to CheckinDatabase().
   
   * lib/query.py
     (form_to_cvsdb_query): Now accept 'cfg' parameter, and set the
       query's row limit from the configured defaults.
     (run_query): Update call to form_to_cvsdb_query().
   
   * docs/url-reference.html
     Remove reference to the 'limit' parameter.

Also:

* CHANGES
  Note this change, referring to it as a 'security fix' due to the
  ramifications of allowing folks to query your potentially monstrous
  database while ignoring your configured response set limits.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2549 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-04-19 21:01:21 +00:00
cmpilato
b1f5af6277 Merge from trunk r2421, whose log message read thusly:
Build the Subversion client context object correctly (thus avoiding a
   weird NULL proxy object pool error).
   
   * lib/vclib/svn/svn_ra.py
     (RemoteSubversionRepository.open): Use svn_client_create_context()
       instead of svn_client_ctx_t().

(Due to changes in the tree structure, the change actually needed to
be applied to lib/vclib/svn_ra/__init__.py.)

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2423 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-08-13 16:23:37 +00:00
cmpilato
47eb36a38a Minor process and verbiage tweak. (Merge from trunk r2393.)
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2395 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-06-02 14:38:39 +00:00
cmpilato
65ee640e2f Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2386 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-06-02 13:23:42 +00:00
cmpilato
ff2e861a14 Let's release 1.0.12 today, shall we?
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2384 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-06-02 12:53:19 +00:00
cmpilato
984a5dada7 Shorten the update/copy instructions. (Merge r2381 from /trunk.)
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2383 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-06-02 12:51:53 +00:00
cmpilato
d23e6f466c Merge from trunk r2369, whose log message read like so:
Fix issue #454 - AttributeError exception trying to escape non-string input.
   
   * lib/sapi.py
     (escape): Ensure that the input is string-ified before doing string
       transformations on it.

   Patch by: Michael Henry <drmikehenry{__AT__}tigris.org>

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2371 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-05-06 13:54:05 +00:00
cmpilato
56bf396432 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2358 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-29 15:52:52 +00:00
cmpilato
d69336d89a Bump copyright year in LICENSE.html.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2354 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-29 15:38:36 +00:00
cmpilato
1ea70fe311 Copyright bumps only.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2351 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-29 15:35:40 +00:00
cmpilato
3b8bb7e39f Update CHANGES file for today's release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2348 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-29 15:24:41 +00:00
cmpilato
a929f630e6 Merge from trunk r2344.
There were too many ways to do something as simple as HTML escaping in
the ViewVC codebase.  Simplify, conjoin, remove, etc.

* lib/sapi.py
  (escape): New function.  *The* preferred HTML-escaping mechanism.
  (Server.escape): New common Server object escape mechanism (which
    uses the aforementioned escape(), of course).
  (CgiServer.escape, WsgiServer.escape, AspServer.escape,
   ModPythonServer.escape): Lose as unnecessary.

* lib/viewvc.py
  (): Replace all uses of cgi.escape() with sapi.escape().
  (prepare_hidden_values): Escape hidden form variable names and values. 
  
* lib/query.py
  (main): Use server.escape() instead of cgi.escape().

* lib/blame.py
  (HTMLBlameSource.__getitem__): Use sapi.escape() instead of
    cgi.escape().

* lib/idiff.py
  (_mdiff_split, _differ_split): Use sapi.escape() instead of
    cgi.escape().


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2346 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-11 20:19:31 +00:00
cmpilato
a0133ce584 Oops! Fix version typos.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2343 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-10 22:01:43 +00:00
cmpilato
fa94d647f3 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2340 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-10 21:50:25 +00:00
cmpilato
c0d0e0b097 Revert change accidentally committed in r2337.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2338 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-10 21:49:13 +00:00
cmpilato
383ad7aac2 Schedule the 1.0.10 release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2337 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-10 21:48:46 +00:00
cmpilato
8a446830cc Merge some copyright bumps.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2336 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-03-10 21:46:49 +00:00
cmpilato
06e8eec7ca Merge from trunk r2325 and r2326:
* lib/viewvc.py
     (query_backup): Switch to using the sapi interface for output file
       I/O instead of using 'print'.
     (view_queryform): Escape user-provided input before passing it
       directly off to the templates.  Can you say "XSS attack vector"?

Also:

* CHANGES
  Note the security fix.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2329 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-02-10 19:44:30 +00:00
cmpilato
0225c7dc13 Merge from trunk r2265 whose log message read:
Fix issue #427 - regex filtering broken by bogus validator function.
   
   * lib/viewvc.py
     (_validate_regex): Try compiling the incoming regex, returning True
       on success and None otherwise.  (Simply 'pass'ing caused all
       regexs to fail validation.)
   
   Patch by: Robert Fleming <flemingr{_AT_}tigris.org>

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2328 8cb11bc2-c004-0410-86c3-e597b4017df7
2010-02-10 19:41:15 +00:00
cmpilato
b08bea6a1d Merge r2303 from trunk (or, the deletion half of the viewvc.org directory
move, at least).

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2305 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-12-04 21:52:32 +00:00
cmpilato
ac34cc35ce Partially merge from trunk r1875 in order to fix some bugs viewing
resources in remote Subversion repositories that have spaces (or other
URI-unsafe characters) in their names.

* lib/vclib/svn_ra/__init__.py
  (): Import urllib.
  (SubversionRepository._geturl): New.
  (temp_checkout, SubversionRepository.openfile,
   SubversionRepository.itemlog, SubversionRepository.annotate,
   SubversionRepository._get_dirents): Use new _geturl() function to
    construct URLs.

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2243 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-08-17 15:14:04 +00:00
cmpilato
1567b2ee0c Begin a new release cycle, the sequel.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2237 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-08-11 13:10:15 +00:00
cmpilato
3ce548a72b Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2233 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-08-11 13:01:53 +00:00
cmpilato
c771aa971c Let's roll 1.0.9 today.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2231 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-08-11 12:57:48 +00:00
cmpilato
0adab05e44 Merge from trunk r2225, whose log message read:
* lib/viewvc.py
     (view_error): Settle for simple HTML-escaping of error messages
       rather than full htmlification.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2227 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-07-14 20:46:22 +00:00
cmpilato
f45fc973b7 Merge from trunk r2217, whose log message read thusly:
Try to avoid content spoofing errors.  Prior to this change, a URL
   like this:
   
      http://localhost/viewvc/subversion/?view=foo%22)%20was%20passed\
      %20as%20a%20parameter.20%20Visit%20http://www.baddy.com%20to%20\
      figure%20out%20why%20(%22foo
   
   Would result in an error page that read as follows:
   
      An illegal value ("foo") was passed as a parameter. Visit
      http://www.baddy.com to figure out why ("foo") was passed as a
      parameter.
   
   (where "http://www.baddy.com" was linkified, and could potentially
   point to a malicious website.)
   
   With this change, we will avoid printing unknown parameter names, and
   will show the parameter name rather its value when a bogus value is
   detected.  Yes, there's admittedly some information loss here that
   might be useful to the well-meaning but fat-fingered user, but the
   security aspect is more important.
   
   * lib/viewvc.py
     (_validate_param): Don't print illegal parameter names, and show the
       (legal) parameter name rather than its value when that value is
       illegal.

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2219 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-07-06 19:06:51 +00:00
cmpilato
14b35861c2 * lib/viewvc.py
(Request.run_viewvc): Oops!  Remove a mapping of view=rev to view=revision
    picked up during the backport of trunk changes committed in r2214.
    ViewVC 1.0.x still uses view=rev!


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2216 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-07-06 16:52:56 +00:00
cmpilato
6f0e5334ff ### NOTE: Part of this was reverted in r2216. ###
Merge from trunk r2211, r2212, and r2213, whose combined log message
might have read as follows:

   * lib/viewvc.py
     (_validate_view, _validate_mimetype): New validation functions.
     (_re_validate_mimetype): Removed as unused.
     (_legal_params): Tweak the validation routines for 'view' and
       'content-type' to point to _validate_view() and _validate_mimetype(),
       respectively.
     (_validate_param): Now check for non-zero result from validation
       functions as the "valid" indicator, rather than requiring each of
       them to raise an exception in troubled times.
     (Request.run_viewvc): Use an intermediate variable to simplify some
       logic around input parameter validation.  Move the logic that maps
       view=rev to view=revision into the parameter validation loop.
       Lose now-unnecessary validation of 'content-type' parameter -- the
       normal parameter validation stuff should catch problems there.

Also:

* CHANGES
  Record the relevant bits of these changes.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2214 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-07-06 16:45:40 +00:00
cmpilato
5129453aa8 Merge from trunk r2201, which contains some minor documentation
markup tweaks.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2203 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-06-15 20:12:57 +00:00
cmpilato
59b1e1d817 Add placeholder for 1.0.9's CHANGES.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2155 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-05 17:28:36 +00:00
cmpilato
fde7ddfa78 * lib/viewvc.py
(__version__): Bump to 1.0.9-dev.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2154 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-05 17:27:48 +00:00
cmpilato
e55a53826a Let's pretend we'll release 1.0.8 today, shall we?
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2149 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-05 17:12:06 +00:00
cmpilato
2e42e8210a Update copyright years.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2145 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-05 17:06:06 +00:00
cmpilato
07019eaf2b Backport from trunk r2137: Fix issue #409, an exception thrown when
sorting by revision in a remote Subversion directory view.

* lib/vclib/svn_ra/__init__.py
  (get_logs): Store the entry's revision as a string, for consistency
    with other vclib modules.

Also:

* CHANGES
  Record this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2138 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-05 14:57:37 +00:00
cmpilato
ee17367b8b Backport to the 1.0.x branch trunk's r2134, whose log message read thusly:
Fix an exception in log views of Subversion repositories with 0
   revisions.
   
   * lib/vclib/svn/__init__.py
     (_get_history): Add easy-out for repositories with 0 revisions.
   
   Reported by: Wojciech Wróblewski <wojtek{_AT_}elmi.pl>

Also:

* CHANGES
  Note this fix.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2136 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-05-04 15:00:22 +00:00
cmpilato
63e89c6517 Merge from trunk r2128-2129.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2131 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-04-20 17:42:06 +00:00
cmpilato
89c5af7d9d Update copyright years.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2109 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-03-18 16:56:29 +00:00
cmpilato
743fcdd6ae Merge from trunk r2103, whose log message read thusly:
Fix namespace problem with raised Exception.
   
   * lib/viewvc.py
     (view_revision): raise *debug.*ViewVCException.
   
   Patch by: Kamesh Jayachandran <kamesh@collab.net>


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2105 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-03-18 12:52:59 +00:00
cmpilato
9451f373e8 Merge from trunk r2097, whose log message read thusly:
Finish issue #396 - Malformed accept-language header crashes viewvc
   
   * lib/accept.py
     (AcceptLanguageParseError): Was AcceptParseError.
     (_parse): Track renamed Exception.
   
   * lib/viewvc.py
     (Request.__init__): Catch and handle raised AcceptLanguageParseError.
   
   Patch by: Rune Halvorsen <runefh{_AT_}gmail.com>,
             me

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2100 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-02-26 16:16:40 +00:00
cmpilato
c0ce6b9dbe Merge from trunk r2090, whose log message read thusly:
ViewVC doesn't "do" directory entry sorting by revision for CVS, so
   don't imply that it does in the UI.
   
   * lib/viewvc.py
     (view_directory): Don't provide sortby_rev_href to the template.
   
   * templates/directory.ezt
     Only offer sort links when those links are provided by ViewVC.
   
   * templates/dir_new.ezt
     Only offer sort links when those links are provided by ViewVC.  Use
     date-based sorting if rev-based sorting isn't available.

Also:

* CHANGES
  Note this change.



git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2093 8cb11bc2-c004-0410-86c3-e597b4017df7
2009-02-20 15:31:27 +00:00
cmpilato
e498d9fdbe Record a bunch of old merges (as determined from log message harvesting)
in Subversion's mergeinfo tracking system.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2061 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-12-05 17:23:38 +00:00
cmpilato
1bb0b7ee38 Merge r2048 from trunk.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2050 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-11-13 20:09:01 +00:00
cmpilato
7bafa7b77e Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2020 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-10-14 22:06:35 +00:00
cmpilato
1bc2914f4b Finalize release date for 1.0.7. Need to get this regression fix available.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2018 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-10-14 21:47:06 +00:00
cmpilato
06f6ba27d0 Backport from trunk r2016, whose log message reads thusly:
Fix issue #373: Regression: "as text" view no longer transmits
   Content-type: text/plain header.
   
   * lib/viewvc.py
     (Request.run_viewvc): Add 'text/plain' to the list of content types
       allowed to be specified via the CGI query params.
     (view_checkout): Revert the change from r1978 which caused this to
       ignore the content-type query param; we'll go back to paying
       attention to that, and simply trust that Request.run_viewvc() has
       sanitized it.

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2017 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-10-02 15:57:59 +00:00
cmpilato
6cf12dd9b3 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.0.x@2006 8cb11bc2-c004-0410-86c3-e597b4017df7
2008-09-16 19:05:57 +00:00
60 changed files with 324 additions and 1269 deletions

37
CHANGES
View File

@@ -1,3 +1,40 @@
Version 1.0.13 (released 24-Oct-2012)
* security fix: escape "extra" diff info to avoid XSS attack (issue #515)
* security fix: remove user-reachable override of cvsdb row limit
* fix obscure "unexpected NULL parent pool" Subversion bindings error
* fix svndbadmin failure on deleted paths under Subversion 1.7 (issue #499)
Version 1.0.12 (released 02-Jun-2010)
* fix exception caused by trying to HTML-escape non-string data (issue #454)
Version 1.0.11 (released 29-Mar-2010)
* security fix: escape user-provided search_re input to avoid XSS attack
Version 1.0.10 (released 10-Mar-2010)
* security fix: escape user-provided query form input to avoid XSS attack
* fix errors viewing remote Subversion paths with URI-unsafe characters
* fix regexp input validation (issue #426, #427, #440)
Version 1.0.9 (released 11-Aug-2009)
* security fix: validate the 'view' parameter to avoid XSS attack
* security fix: avoid printing illegal parameter names and values
Version 1.0.8 (released 05-May-2009)
* fix directory view sorting UI
* tolerate malformed Accept-Language headers (issue #396)
* fix directory log views in revision-less Subversion repositories
* fix exception in rev-sorted remote Subversion directory views (issue #409)
Version 1.0.7 (released 14-Oct-2008)
* fix regression in the 'as text' download view (issue #373)
Version 1.0.6 (released 16-Sep-2008) Version 1.0.6 (released 16-Sep-2008)
* security fix: ignore arbitrary user-provided MIME types (issue #354) * security fix: ignore arbitrary user-provided MIME types (issue #354)

View File

@@ -34,7 +34,7 @@ Congratulations on getting this far. :-)
(http://www.python.org/) (http://www.python.org/)
* Subversion, Version Control System, 1.2.0 or later * Subversion, Version Control System, 1.2.0 or later
(binary installation and Python bindings) (binary installation and Python bindings)
(http://subversion.tigris.org/) (http://subversion.apache.org/)
Optional: Optional:

View File

@@ -15,7 +15,7 @@
<blockquote> <blockquote>
<p><strong>Copyright &copy; 1999-2008 The ViewCVS Group. All rights <p><strong>Copyright &copy; 1999-2012 The ViewCVS Group. All rights
reserved.</strong></p> reserved.</strong></p>
<p>By using ViewVC, you agree to the terms and conditions set forth <p>By using ViewVC, you agree to the terms and conditions set forth
@@ -59,6 +59,9 @@
<li>March 17, 2006 &mdash; software renamed from "ViewCVS"</li> <li>March 17, 2006 &mdash; software renamed from "ViewCVS"</li>
<li>April 10, 2007 &mdash; copyright years updated</li> <li>April 10, 2007 &mdash; copyright years updated</li>
<li>February 22, 2008 &mdash; copyright years updated</li> <li>February 22, 2008 &mdash; copyright years updated</li>
<li>March 29, 2010 &mdash; copyright years updated</li>
<li>February 18, 2011 &mdash; copyright years updated</li>
<li>January 23, 2012 &mdash; copyright years updated</li>
</ul> </ul>
</body> </body>

View File

@@ -3,7 +3,7 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -3,7 +3,7 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004 James Henstridge # Copyright (C) 2004 James Henstridge
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
@@ -154,7 +155,7 @@ class SvnRev:
fsroot = self._get_root_for_rev(rev) fsroot = self._get_root_for_rev(rev)
# find changes in the revision # find changes in the revision
editor = svn.repos.RevisionChangeCollector(repo.fs, rev, pool) editor = svn.repos.ChangeCollector(repo.fs, fsroot, pool)
e_ptr, e_baton = svn.delta.make_editor(editor, pool) e_ptr, e_baton = svn.delta.make_editor(editor, pool)
svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton, pool) svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton, pool)
@@ -168,22 +169,35 @@ class SvnRev:
if change.item_kind != svn.core.svn_node_file: continue if change.item_kind != svn.core.svn_node_file: continue
# deal with the change types we handle # deal with the change types we handle
action = None
base_root = None base_root = None
base_path = change.base_path
if change.base_path: if change.base_path:
base_root = self._get_root_for_rev(change.base_rev) base_root = self._get_root_for_rev(change.base_rev)
if not change.path: # figure out what kind of change this is, and get a diff
# object for it. note that prior to 1.4 Subversion's
# bindings didn't give us change.action, but that's okay
# because back then deleted paths always had a change.path
# of None.
if hasattr(change, 'action') \
and change.action == svn.repos.CHANGE_ACTION_DELETE:
action = 'remove'
elif not change.path:
action = 'remove' action = 'remove'
elif change.added: elif change.added:
action = 'add' action = 'add'
else: else:
action = 'change' action = 'change'
diffobj = svn.fs.FileDiff(base_root and base_root or None, if action == 'remove':
base_root and change.base_path or None, diffobj = svn.fs.FileDiff(base_root, base_path, None, None,
change.path and fsroot or None, subpool, [])
change.path and change.path or None, else:
subpool, []) diffobj = svn.fs.FileDiff(base_root, base_path,
fsroot, change.path,
subpool, [])
diff_fp = diffobj.get_pipe() diff_fp = diffobj.get_pipe()
plus, minus = _get_diff_counts(diff_fp) plus, minus = _get_diff_counts(diff_fp)
self.changes.append((path, action, plus, minus)) self.changes.append((path, action, plus, minus))

View File

@@ -867,7 +867,7 @@ th.caption {
<td>file query string</td> <td>file query string</td>
</tr> </tr>
<tr> <tr>
<td><code>file_match=FILE_MATCH</code></td> <td><code>file_match=<var>FILE_MATCH</var></code></td>
<td>optional</td> <td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td> <td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td>
</tr> </tr>
@@ -877,37 +877,37 @@ th.caption {
<td>author query string</td> <td>author query string</td>
</tr> </tr>
<tr> <tr>
<td><code>who_match=WHO_MATCH</code></td> <td><code>who_match=<var>WHO_MATCH</var></code></td>
<td>optional</td> <td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td> <td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td>
</tr> </tr>
<tr> <tr>
<td><code>querysort=SORT</code></td> <td><code>querysort=<var>SORT</var></code></td>
<td>optional</td> <td>optional</td>
<td>"date" "author" or "file" determining order of query results</td> <td>"date" "author" or "file" determining order of query results</td>
</tr> </tr>
<tr> <tr>
<td><code>date=DATE</code></td> <td><code>date=<var>DATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td> <td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td>
</tr> </tr>
<tr> <tr>
<td><code>hours=HOURS</code></td> <td><code>hours=<var>HOURS</var></code></td>
<td>optional</td> <td>optional</td>
<td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td> <td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td>
</tr> </tr>
<tr> <tr>
<td><code>mindate=MINDATE</code></td> <td><code>mindate=<var>MINDATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td> <td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
</tr> </tr>
<tr> <tr>
<td><code>maxdate=MAXDATE</code></td> <td><code>maxdate=<var>MAXDATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td> <td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
</tr> </tr>
<tr> <tr>
<td><code>limit_changes=LIMIT_CHANGES</code></td> <td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
<td>optional</td> <td>optional</td>
<td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td> <td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td>
</tr> </tr>
@@ -965,7 +965,7 @@ th.caption {
<td>branch query string</td> <td>branch query string</td>
</tr> </tr>
<tr> <tr>
<td><code>branch_match=BRANCH_MATCH</code></td> <td><code>branch_match=<var>BRANCH_MATCH</var></code></td>
<td>optional</td> <td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of branch match</td> <td>"exact" "like" "glob" "regex" or "notregex" determining type of branch match</td>
</tr> </tr>
@@ -980,7 +980,7 @@ th.caption {
<td>file query string</td> <td>file query string</td>
</tr> </tr>
<tr> <tr>
<td><code>file_match=FILE_MATCH</code></td> <td><code>file_match=<var>FILE_MATCH</var></code></td>
<td>optional</td> <td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td> <td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td>
</tr> </tr>
@@ -990,47 +990,42 @@ th.caption {
<td>author query string</td> <td>author query string</td>
</tr> </tr>
<tr> <tr>
<td><code>who_match=WHO_MATCH</code></td> <td><code>who_match=<var>WHO_MATCH</var></code></td>
<td>optional</td> <td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td> <td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td>
</tr> </tr>
<tr> <tr>
<td><code>querysort=SORT</code></td> <td><code>querysort=<var>SORT</var></code></td>
<td>optional</td> <td>optional</td>
<td>"date" "author" or "file" determining order of query results</td> <td>"date" "author" or "file" determining order of query results</td>
</tr> </tr>
<tr> <tr>
<td><code>date=DATE</code></td> <td><code>date=<var>DATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td> <td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td>
</tr> </tr>
<tr> <tr>
<td><code>hours=HOURS</code></td> <td><code>hours=<var>HOURS</var></code></td>
<td>optional</td> <td>optional</td>
<td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td> <td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td>
</tr> </tr>
<tr> <tr>
<td><code>mindate=MINDATE</code></td> <td><code>mindate=<var>MINDATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td> <td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
</tr> </tr>
<tr> <tr>
<td><code>maxdate=MAXDATE</code></td> <td><code>maxdate=<var>MAXDATE</var></code></td>
<td>optional</td> <td>optional</td>
<td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td> <td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
</tr> </tr>
<tr> <tr>
<td><code>format=FORMAT</code></td> <td><code>format=<var>FORMAT</var></code></td>
<td>optional</td> <td>optional</td>
<td>"rss" or "backout" values to generate an rss feed or list of commands to back out changes instead showing a normal query result page</td> <td>"rss" or "backout" values to generate an rss feed or list of commands to back out changes instead showing a normal query result page</td>
</tr> </tr>
<tr> <tr>
<td><code>limit=LIMIT</code></td> <td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
<td>optional</td>
<td>maximum number of file-revisions to process during a query. Default is value of <code>row_limit</code> configuration option</td>
</tr>
<tr>
<td><code>limit_changes=LIMIT_CHANGES</code></td>
<td>optional</td> <td>optional</td>
<td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td> <td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td>
</tr> </tr>
@@ -1082,7 +1077,7 @@ th.caption {
<td><a href="#revision-param"><code>revision</code> parameter</a></td> <td><a href="#revision-param"><code>revision</code> parameter</a></td>
</tr> </tr>
<tr> <tr>
<td><code>limit_changes=LIMIT_CHANGES</code></td> <td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
<td>optional</td> <td>optional</td>
<td>maximum number of files to list per commit. Default is value of <code>limit_changes</code> configuration option</td> <td>maximum number of files to list per commit. Default is value of <code>limit_changes</code> configuration option</td>
</tr> </tr>

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -39,7 +39,7 @@ def _parse(hdr, result):
while pos < len(hdr): while pos < len(hdr):
name = _re_token.match(hdr, pos) name = _re_token.match(hdr, pos)
if not name: if not name:
raise AcceptParseError() raise AcceptLanguageParseError()
a = result.item_class(string.lower(name.group(1))) a = result.item_class(string.lower(name.group(1)))
pos = name.end() pos = name.end()
while 1: while 1:
@@ -210,7 +210,7 @@ class _LanguageSelector:
def append(self, item): def append(self, item):
self.requested.append(item) self.requested.append(item)
class AcceptParseError(Exception): class AcceptLanguageParseError(Exception):
pass pass
def _test(): def _test():

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org> # Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
@@ -31,9 +31,8 @@ import os
import re import re
import time import time
import math import math
import cgi
import vclib import vclib
import sapi
re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"') re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
@@ -81,7 +80,7 @@ class HTMLBlameSource:
diff_url = None diff_url = None
if item.prev_rev: if item.prev_rev:
diff_url = '%sr1=%s&amp;r2=%s' % (self.diff_url, item.prev_rev, item.rev) diff_url = '%sr1=%s&amp;r2=%s' % (self.diff_url, item.prev_rev, item.rev)
thisline = link_includes(cgi.escape(item.text), self.repos, thisline = link_includes(sapi.escape(item.text), self.repos,
self.path_parts, self.include_url) self.path_parts, self.include_url)
return _item(text=thisline, line_number=item.line_number, return _item(text=thisline, line_number=item.line_number,
rev=item.rev, prev_rev=item.prev_rev, rev=item.rev, prev_rev=item.prev_rev,

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -29,13 +29,12 @@ error = "cvsdb error"
## complient database interface ## complient database interface
class CheckinDatabase: class CheckinDatabase:
def __init__(self, host, port, user, passwd, database, row_limit): def __init__(self, host, port, user, passwd, database):
self._host = host self._host = host
self._port = port self._port = port
self._user = user self._user = user
self._passwd = passwd self._passwd = passwd
self._database = database self._database = database
self._row_limit = row_limit
## database lookup caches ## database lookup caches
self._get_cache = {} self._get_cache = {}
@@ -349,13 +348,11 @@ class CheckinDatabase:
conditions = string.join(joinConds + condList, " AND ") conditions = string.join(joinConds + condList, " AND ")
conditions = conditions and "WHERE %s" % conditions conditions = conditions and "WHERE %s" % conditions
## limit the number of rows requested or we could really slam ## apply the query's row limit, if any (so we avoid really
## a server with a large database ## slamming a server with a large database)
limit = "" limit = ""
if query.limit: if query.limit:
limit = "LIMIT %s" % (str(query.limit)) limit = "LIMIT %s" % (str(query.limit))
elif self._row_limit:
limit = "LIMIT %s" % (str(self._row_limit))
sql = "SELECT checkins.* FROM %s %s %s %s" % ( sql = "SELECT checkins.* FROM %s %s %s %s" % (
tables, conditions, order_by, limit) tables, conditions, order_by, limit)
@@ -594,8 +591,8 @@ class QueryEntry:
self.data = data self.data = data
self.match = match self.match = match
## CheckinDatabaseQueryData is a object which contains the search parameters ## CheckinDatabaseQuery is an object which contains the search
## for a query to the CheckinDatabase ## parameters for a query to the Checkin Database
class CheckinDatabaseQuery: class CheckinDatabaseQuery:
def __init__(self): def __init__(self):
## sorting ## sorting
@@ -682,7 +679,7 @@ def ConnectDatabase(cfg, readonly=0):
user = cfg.cvsdb.user user = cfg.cvsdb.user
passwd = cfg.cvsdb.passwd passwd = cfg.cvsdb.passwd
db = CheckinDatabase(cfg.cvsdb.host, cfg.cvsdb.port, user, passwd, db = CheckinDatabase(cfg.cvsdb.host, cfg.cvsdb.port, user, passwd,
cfg.cvsdb.database_name, cfg.cvsdb.row_limit) cfg.cvsdb.database_name)
db.Connect() db.Connect()
return db return db

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -38,13 +38,17 @@ if SHOW_TIMES:
else: else:
_times[which] = t _times[which] = t
def dump(): def t_dump(out):
for name, value in _times.items(): out.write('<div>')
print '%s: %.6f<br />' % (name, value) names = _times.keys()
names.sort()
for name in names:
out.write('%s: %.6fs<br/>\n' % (name, _times[name]))
out.write('</div>')
else: else:
t_start = t_end = dump = lambda *args: None t_start = t_end = t_dump = lambda *args: None
class ViewVCException: class ViewVCException:

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -20,7 +20,7 @@ import difflib
import sys import sys
import re import re
import ezt import ezt
import cgi import sapi
def sidebyside(fromlines, tolines, context): def sidebyside(fromlines, tolines, context):
"""Generate side by side diff""" """Generate side by side diff"""
@@ -49,18 +49,18 @@ def _mdiff_split(flag, (line_number, text)):
while True: while True:
m = _re_mdiff.search(text, pos) m = _re_mdiff.search(text, pos)
if not m: if not m:
segments.append(_item(text=cgi.escape(text[pos:]), type=None)) segments.append(_item(text=sapi.escape(text[pos:]), type=None))
break break
if m.start() > pos: if m.start() > pos:
segments.append(_item(text=cgi.escape(text[pos:m.start()]), type=None)) segments.append(_item(text=sapi.escape(text[pos:m.start()]), type=None))
if m.group(1) == "+": if m.group(1) == "+":
segments.append(_item(text=cgi.escape(m.group(2)), type="add")) segments.append(_item(text=sapi.escape(m.group(2)), type="add"))
elif m.group(1) == "-": elif m.group(1) == "-":
segments.append(_item(text=cgi.escape(m.group(2)), type="remove")) segments.append(_item(text=sapi.escape(m.group(2)), type="remove"))
elif m.group(1) == "^": elif m.group(1) == "^":
segments.append(_item(text=cgi.escape(m.group(2)), type="change")) segments.append(_item(text=sapi.escape(m.group(2)), type="change"))
pos = m.end() pos = m.end()
@@ -166,12 +166,12 @@ def _differ_split(row, guide):
for m in _re_differ.finditer(guide, pos): for m in _re_differ.finditer(guide, pos):
if m.start() > pos: if m.start() > pos:
segments.append(_item(text=cgi.escape(line[pos:m.start()]), type=None)) segments.append(_item(text=sapi.escape(line[pos:m.start()]), type=None))
segments.append(_item(text=cgi.escape(line[m.start():m.end()]), segments.append(_item(text=sapi.escape(line[m.start():m.end()]),
type="change")) type="change"))
pos = m.end() pos = m.end()
segments.append(_item(text=cgi.escape(line[pos:]), type=None)) segments.append(_item(text=sapi.escape(line[pos:]), type=None))
return _item(gap=ezt.boolean(gap), type=type, segments=segments, return _item(gap=ezt.boolean(gap), type=type, segments=segments,
left_number=left_number, right_number=right_number) left_number=left_number, right_number=right_number)

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -217,8 +217,9 @@ def decode_command(cmd):
else: else:
return "exact" return "exact"
def form_to_cvsdb_query(form_data): def form_to_cvsdb_query(cfg, form_data):
query = cvsdb.CreateCheckinQuery() query = cvsdb.CreateCheckinQuery()
query.SetLimit(cfg.cvsdb.row_limit)
if form_data.repository: if form_data.repository:
for cmd, str in listparse_string(form_data.repository): for cmd, str in listparse_string(form_data.repository):
@@ -338,7 +339,7 @@ def build_commit(server, cfg, desc, files, cvsroots, viewvc_link):
return ob return ob
def run_query(server, cfg, form_data, viewvc_link): def run_query(server, cfg, form_data, viewvc_link):
query = form_to_cvsdb_query(form_data) query = form_to_cvsdb_query(cfg, form_data)
db = cvsdb.ConnectDatabaseReadOnly(cfg) db = cvsdb.ConnectDatabaseReadOnly(cfg)
db.RunQuery(query) db.RunQuery(query)
@@ -398,12 +399,11 @@ def main(server, cfg, viewvc_link):
'cfg' : cfg, 'cfg' : cfg,
'address' : cfg.general.address, 'address' : cfg.general.address,
'vsn' : viewvc.__version__, 'vsn' : viewvc.__version__,
'repository' : server.escape(form_data.repository),
'repository' : server.escape(form_data.repository, 1), 'branch' : server.escape(form_data.branch),
'branch' : server.escape(form_data.branch, 1), 'directory' : server.escape(form_data.directory),
'directory' : server.escape(form_data.directory, 1), 'file' : server.escape(form_data.file),
'file' : server.escape(form_data.file, 1), 'who' : server.escape(form_data.who),
'who' : server.escape(form_data.who, 1),
'docroot' : cfg.options.docroot is None \ 'docroot' : cfg.options.docroot is None \
and viewvc_link + '/' + viewvc.docroot_magic_path \ and viewvc_link + '/' + viewvc.docroot_magic_path \
or cfg.options.docroot, or cfg.options.docroot,

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -20,6 +20,7 @@ import string
import os import os
import sys import sys
import re import re
import cgi
# global server object. It will be either a CgiServer or a proxy to # global server object. It will be either a CgiServer or a proxy to
@@ -27,6 +28,19 @@ import re
server = None server = None
# Simple HTML string escaping. Note that we always escape the
# double-quote character -- ViewVC shouldn't ever need to preserve
# that character as-is, and sometimes needs to embed escaped values
# into HTML attributes.
def escape(s):
s = str(s)
s = string.replace(s, '&', '&amp;')
s = string.replace(s, '>', '&gt;')
s = string.replace(s, '<', '&lt;')
s = string.replace(s, '"', "&quot;")
return s
class Server: class Server:
def __init__(self): def __init__(self):
self.pageGlobals = {} self.pageGlobals = {}
@@ -34,6 +48,9 @@ class Server:
def self(self): def self(self):
return self return self
def escape(self, s):
return escape(s)
def close(self): def close(self):
pass pass
@@ -129,9 +146,6 @@ class CgiServer(Server):
global server global server
server = self server = self
global cgi
import cgi
def addheader(self, name, value): def addheader(self, name, value):
self.headers.append((name, value)) self.headers.append((name, value))
@@ -161,9 +175,6 @@ class CgiServer(Server):
print 'This document is located <a href="%s">here</a>.' % url print 'This document is located <a href="%s">here</a>.' % url
sys.exit(0) sys.exit(0)
def escape(self, s, quote = None):
return cgi.escape(s, quote)
def getenv(self, name, value=None): def getenv(self, name, value=None):
ret = os.environ.get(name, value) ret = os.environ.get(name, value)
if self.iis and name == 'PATH_INFO' and ret: if self.iis and name == 'PATH_INFO' and ret:
@@ -221,9 +232,6 @@ class AspServer(ThreadedServer):
self.response.Redirect(url) self.response.Redirect(url)
sys.exit() sys.exit()
def escape(self, s, quote = None):
return self.server.HTMLEncode(str(s))
def getenv(self, name, value = None): def getenv(self, name, value = None):
ret = self.request.ServerVariables(name)() ret = self.request.ServerVariables(name)()
if not type(ret) is types.UnicodeType: if not type(ret) is types.UnicodeType:
@@ -285,9 +293,6 @@ class ModPythonServer(ThreadedServer):
self.request = request self.request = request
self.headerSent = 0 self.headerSent = 0
global cgi
import cgi
def addheader(self, name, value): def addheader(self, name, value):
self.request.headers_out.add(name, value) self.request.headers_out.add(name, value)
@@ -311,9 +316,6 @@ class ModPythonServer(ThreadedServer):
% (url, url)) % (url, url))
sys.exit() sys.exit()
def escape(self, s, quote = None):
return cgi.escape(s, quote)
def getenv(self, name, value = None): def getenv(self, name, value = None):
try: try:
return self.request.subprocess_env[name] return self.request.subprocess_env[name]

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org> # Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -239,6 +239,9 @@ class NodeHistory:
def _get_history(svnrepos, full_name, rev, options={}): def _get_history(svnrepos, full_name, rev, options={}):
if svnrepos.youngest == 0:
return {}
fsroot = svnrepos._getroot(rev) fsroot = svnrepos._getroot(rev)
show_all_logs = options.get('svn_show_all_dir_logs', 0) show_all_logs = options.get('svn_show_all_dir_logs', 0)
if not show_all_logs: if not show_all_logs:

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -20,6 +20,7 @@ import re
import tempfile import tempfile
import popen2 import popen2
import time import time
import urllib
from vclib.svn import Revision, ChangedPath, _datestr_to_date, _compare_paths, _cleanup_path from vclib.svn import Revision, ChangedPath, _datestr_to_date, _compare_paths, _cleanup_path
from svn import core, delta, client, wc, ra from svn import core, delta, client, wc, ra
@@ -220,7 +221,7 @@ def get_logs(svnrepos, full_name, rev, files):
rev, author, date, log, changes = \ rev, author, date, log, changes = \
_get_rev_details(svnrepos, entry.created_rev, subpool) _get_rev_details(svnrepos, entry.created_rev, subpool)
rev_info_cache[entry.created_rev] = rev, author, date, log rev_info_cache[entry.created_rev] = rev, author, date, log
file.rev = rev file.rev = str(rev)
file.author = author file.author = author
file.date = _datestr_to_date(date, subpool) file.date = _datestr_to_date(date, subpool)
file.log = log file.log = log
@@ -234,7 +235,7 @@ def temp_checkout(svnrepos, path, rev, pool):
"""Check out file revision to temporary file""" """Check out file revision to temporary file"""
temp = tempfile.mktemp() temp = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(temp, pool) stream = core.svn_stream_from_aprfile(temp, pool)
url = svnrepos.rootpath + (path and '/' + path) url = svnrepos._geturl(path)
client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev), client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev),
svnrepos.ctx, pool) svnrepos.ctx, pool)
core.svn_stream_close(stream) core.svn_stream_close(stream)
@@ -285,7 +286,7 @@ class SubversionRepository(vclib.Repository):
self.rootpath = rootpath self.rootpath = rootpath
# Setup the client context baton, complete with non-prompting authstuffs. # Setup the client context baton, complete with non-prompting authstuffs.
ctx = client.svn_client_ctx_t() ctx = client.svn_client_create_context()
providers = [] providers = []
providers.append(client.svn_client_get_simple_provider(pool)) providers.append(client.svn_client_get_simple_provider(pool))
providers.append(client.svn_client_get_username_provider(pool)) providers.append(client.svn_client_get_username_provider(pool))
@@ -323,10 +324,10 @@ class SubversionRepository(vclib.Repository):
raise vclib.ItemNotFound(path_parts) raise vclib.ItemNotFound(path_parts)
def openfile(self, path_parts, rev): def openfile(self, path_parts, rev):
path = self._getpath(path_parts)
rev = self._getrev(rev) rev = self._getrev(rev)
url = self.rootpath url = self._geturl(path)
if len(path_parts):
url = self.rootpath + '/' + self._getpath(path_parts)
tmp_file = tempfile.mktemp() tmp_file = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(tmp_file, self.pool) stream = core.svn_stream_from_aprfile(tmp_file, self.pool)
### rev here should be the last history revision of the URL ### rev here should be the last history revision of the URL
@@ -353,18 +354,15 @@ class SubversionRepository(vclib.Repository):
get_logs(self, self._getpath(path_parts), self._getrev(rev), entries) get_logs(self, self._getpath(path_parts), self._getrev(rev), entries)
def itemlog(self, path_parts, rev, options): def itemlog(self, path_parts, rev, options):
full_name = self._getpath(path_parts) path = self._getpath(path_parts)
rev = self._getrev(rev) rev = self._getrev(rev)
url = self._geturl(path)
# It's okay if we're told to not show all logs on a file -- all # It's okay if we're told to not show all logs on a file -- all
# the revisions should match correctly anyway. # the revisions should match correctly anyway.
lc = LogCollector(full_name, options.get('svn_show_all_dir_logs', 0)) lc = LogCollector(path, options.get('svn_show_all_dir_logs', 0))
dir_url = self.rootpath
if full_name:
dir_url = dir_url + '/' + full_name
cross_copies = options.get('svn_cross_copies', 0) cross_copies = options.get('svn_cross_copies', 0)
client.svn_client_log([dir_url], _rev2optrev(rev), _rev2optrev(1), client.svn_client_log([url], _rev2optrev(rev), _rev2optrev(1),
1, not cross_copies, lc.add_log, 1, not cross_copies, lc.add_log,
self.ctx, self.pool) self.ctx, self.pool)
revs = lc.logs revs = lc.logs
@@ -379,7 +377,7 @@ class SubversionRepository(vclib.Repository):
def annotate(self, path_parts, rev): def annotate(self, path_parts, rev):
path = self._getpath(path_parts) path = self._getpath(path_parts)
rev = self._getrev(rev) rev = self._getrev(rev)
url = self.rootpath + (path and '/' + path) url = self._geturl(path)
blame_data = [] blame_data = []
@@ -429,13 +427,17 @@ class SubversionRepository(vclib.Repository):
raise vclib.InvalidRevision(rev) raise vclib.InvalidRevision(rev)
return rev return rev
def _geturl(self, path=None):
if not path:
return self.rootpath
return self.rootpath + '/' + urllib.quote(path, "/*~")
def _get_dirents(self, path, rev): def _get_dirents(self, path, rev):
dir_url = self._geturl(path)
if path: if path:
key = str(rev) + '/' + path key = str(rev) + '/' + path
dir_url = self.rootpath + '/' + path
else: else:
key = str(rev) key = str(rev)
dir_url = self.rootpath
dirents = self._dirent_cache.get(key) dirents = self._dirent_cache.get(key)
if dirents: if dirents:
return dirents return dirents

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -14,7 +14,7 @@
# #
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
__version__ = '1.0.6' __version__ = '1.0.13'
# this comes from our library; measure the startup time # this comes from our library; measure the startup time
import debug import debug
@@ -25,7 +25,6 @@ debug.t_start('imports')
import sys import sys
import os import os
import sapi import sapi
import cgi
import string import string
import urllib import urllib
import mimetypes import mimetypes
@@ -112,7 +111,10 @@ class Request:
# process the Accept-Language: header # process the Accept-Language: header
hal = server.getenv('HTTP_ACCEPT_LANGUAGE','') hal = server.getenv('HTTP_ACCEPT_LANGUAGE','')
self.lang_selector = accept.language(hal) try:
self.lang_selector = accept.language(hal)
except accept.AcceptLanguageParseError:
self.lang_selector = accept.language('en')
self.language = self.lang_selector.select_from(cfg.general.languages) self.language = self.lang_selector.select_from(cfg.general.languages)
# load the key/value files, given the selected language # load the key/value files, given the selected language
@@ -147,6 +149,9 @@ class Request:
# Process the query params # Process the query params
for name, values in self.server.params().items(): for name, values in self.server.params().items():
# we only care about the first value
value = values[0]
# patch up old queries that use 'cvsroot' to look like they used 'root' # patch up old queries that use 'cvsroot' to look like they used 'root'
if name == 'cvsroot': if name == 'cvsroot':
name = 'root' name = 'root'
@@ -158,17 +163,12 @@ class Request:
needs_redirect = 1 needs_redirect = 1
# validate the parameter # validate the parameter
_validate_param(name, values[0]) _validate_param(name, value)
# only allow the magic ViewVC MIME types to be declared via CGI params
if (name == 'content-type') and \
(not values[0] in (viewcvs_mime_type, alt_mime_type)):
continue
# if we're here, then the parameter is okay # if we're here, then the parameter is okay
self.query_dict[name] = values[0] self.query_dict[name] = value
# handle view parameter # Resolve the view parameter into a handler function.
self.view_func = _views.get(self.query_dict.get('view', None), self.view_func = _views.get(self.query_dict.get('view', None),
self.view_func) self.view_func)
@@ -601,34 +601,48 @@ def _validate_param(name, value):
this function throws an exception. Otherwise, it simply returns None. this function throws an exception. Otherwise, it simply returns None.
""" """
# First things first -- check that we have a legal parameter name.
try: try:
validator = _legal_params[name] validator = _legal_params[name]
except KeyError: except KeyError:
raise debug.ViewVCException( raise debug.ViewVCException(
'An illegal parameter name ("%s") was passed.' % name, 'An illegal parameter name was provided.',
'400 Bad Request') '400 Bad Request')
# Is there a validator? Is it a regex or a function? Validate if
# we can, returning without incident on valid input.
if validator is None: if validator is None:
return return
elif hasattr(validator, 'match'):
if validator.match(value):
return
else:
if validator(value):
return
# is the validator a regex? # If we get here, the input value isn't valid.
if hasattr(validator, 'match'): raise debug.ViewVCException(
if not validator.match(value): 'An illegal value was provided for the "%s" parameter.' % (name),
raise debug.ViewVCException( '400 Bad Request')
'An illegal value ("%s") was passed as a parameter.' %
value, '400 Bad Request')
return
# the validator must be a function
validator(value)
def _validate_regex(value): def _validate_regex(value):
# hmm. there isn't anything that we can do here.
### we need to watch the flow of these parameters through the system ### we need to watch the flow of these parameters through the system
### to ensure they don't hit the page unescaped. otherwise, these ### to ensure they don't hit the page unescaped. otherwise, these
### parameters could constitute a CSS attack. ### parameters could constitute a CSS attack.
pass try:
re.compile(value)
return True
except:
return None
def _validate_view(value):
# Return true iff VALUE is one of our allowed views.
return _views.has_key(value)
def _validate_mimetype(value):
# For security purposes, we only allow mimetypes from a predefined set
# thereof.
return value in (viewcvs_mime_type, alt_mime_type, 'text/plain')
# obvious things here. note that we don't need uppercase for alpha. # obvious things here. note that we don't need uppercase for alpha.
_re_validate_alpha = re.compile('^[a-z]+$') _re_validate_alpha = re.compile('^[a-z]+$')
@@ -637,17 +651,13 @@ _re_validate_number = re.compile('^[0-9]+$')
# when comparing two revs, we sometimes construct REV:SYMBOL, so ':' is needed # when comparing two revs, we sometimes construct REV:SYMBOL, so ':' is needed
_re_validate_revnum = re.compile('^[-_.a-zA-Z0-9:~\\[\\]/]*$') _re_validate_revnum = re.compile('^[-_.a-zA-Z0-9:~\\[\\]/]*$')
# it appears that RFC 2045 also says these chars are legal: !#$%&'*+^{|}~`
# but woah... I'll just leave them out for now
_re_validate_mimetype = re.compile('^[-_.a-zA-Z0-9/]+$')
# date time values # date time values
_re_validate_datetime = re.compile(r'^(\d\d\d\d-\d\d-\d\d(\s+\d\d:\d\d(:\d\d)?)?)?$') _re_validate_datetime = re.compile(r'^(\d\d\d\d-\d\d-\d\d(\s+\d\d:\d\d(:\d\d)?)?)?$')
# the legal query parameters and their validation functions # the legal query parameters and their validation functions
_legal_params = { _legal_params = {
'root' : None, 'root' : None,
'view' : None, 'view' : _validate_view,
'search' : _validate_regex, 'search' : _validate_regex,
'p1' : None, 'p1' : None,
'p2' : None, 'p2' : None,
@@ -673,7 +683,7 @@ _legal_params = {
'tr2' : _re_validate_revnum, 'tr2' : _re_validate_revnum,
'rev' : _re_validate_revnum, 'rev' : _re_validate_revnum,
'revision' : _re_validate_revnum, 'revision' : _re_validate_revnum,
'content-type' : _re_validate_mimetype, 'content-type' : _validate_mimetype,
# for query # for query
'branch' : _validate_regex, 'branch' : _validate_regex,
@@ -689,7 +699,6 @@ _legal_params = {
'mindate' : _re_validate_datetime, 'mindate' : _re_validate_datetime,
'maxdate' : _re_validate_datetime, 'maxdate' : _re_validate_datetime,
'format' : _re_validate_alpha, 'format' : _re_validate_alpha,
'limit' : _re_validate_number,
# for redirect_pathrev # for redirect_pathrev
'orig_path' : None, 'orig_path' : None,
@@ -988,7 +997,7 @@ def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1):
_re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)(://[-a-zA-Z0-9%.~:_/]+)((\?|\&amp;)([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)') _re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)(://[-a-zA-Z0-9%.~:_/]+)((\?|\&amp;)([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)')
_re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})') _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})')
def htmlify(html): def htmlify(html):
html = cgi.escape(html) html = sapi.escape(html)
html = re.sub(_re_rewrite_url, r'<a href="\1">\1</a>', html) html = re.sub(_re_rewrite_url, r'<a href="\1">\1</a>', html)
html = re.sub(_re_rewrite_email, r'<a href="mailto:\1&#64;\2">\1&#64;\2</a>', html) html = re.sub(_re_rewrite_email, r'<a href="mailto:\1&#64;\2">\1&#64;\2</a>', html)
return html return html
@@ -999,7 +1008,7 @@ def format_log(log, cfg, htmlize=1):
if htmlize: if htmlize:
s = htmlify(log[:cfg.options.short_log_len]) s = htmlify(log[:cfg.options.short_log_len])
else: else:
s = cgi.escape(log[:cfg.options.short_log_len]) s = sapi.escape(log[:cfg.options.short_log_len])
if len(log) > cfg.options.short_log_len: if len(log) > cfg.options.short_log_len:
s = s + '...' s = s + '...'
return s return s
@@ -1323,7 +1332,7 @@ def markup_stream_python(fp, cfg):
### It doesn't escape stuff quite right, nor does it munge URLs and ### It doesn't escape stuff quite right, nor does it munge URLs and
### mailtos as well as we do. ### mailtos as well as we do.
html = cgi.escape(fp.read()) html = sapi.escape(fp.read())
pp = py2html.PrettyPrint(PyFontify.fontify, "rawhtml", "color") pp = py2html.PrettyPrint(PyFontify.fontify, "rawhtml", "color")
pp.set_mode_rawhtml_color() pp.set_mode_rawhtml_color()
html = pp.fontify(html) html = pp.fontify(html)
@@ -1476,7 +1485,7 @@ def prepare_hidden_values(params):
hidden_values = [] hidden_values = []
for name, value in params.items(): for name, value in params.items():
hidden_values.append('<input type="hidden" name="%s" value="%s" />' % hidden_values.append('<input type="hidden" name="%s" value="%s" />' %
(name, value)) (sapi.escape(name), sapi.escape(value)))
return string.join(hidden_values, '') return string.join(hidden_values, '')
def sort_file_data(file_data, roottype, sortdir, sortby, group_dirs): def sort_file_data(file_data, roottype, sortdir, sortby, group_dirs):
@@ -1723,6 +1732,9 @@ def view_directory(request):
data['sortby_%s_href' % sortby] = request.get_url(params={'sortdir': data['sortby_%s_href' % sortby] = request.get_url(params={'sortdir':
revsortdir}, revsortdir},
escape=1) escape=1)
# CVS doesn't support sorting by rev
if request.roottype == "cvs":
data['sortby_rev_href'] = None
# set cvs-specific fields # set cvs-specific fields
if request.roottype == 'cvs': if request.roottype == 'cvs':
@@ -2184,7 +2196,8 @@ def view_checkout(request):
# The revision number acts as a strong validator. # The revision number acts as a strong validator.
if not check_freshness(request, None, revision): if not check_freshness(request, None, revision):
request.server.header(request.mime_type or 'text/plain') request.server.header(request.query_dict.get('content-type')
or request.mime_type or 'text/plain')
copy_stream(fp) copy_stream(fp)
fp.close() fp.close()
@@ -2444,7 +2457,7 @@ class DiffSource:
return _item(type='header', return _item(type='header',
line_info_left=match.group(1), line_info_left=match.group(1),
line_info_right=match.group(2), line_info_right=match.group(2),
line_info_extra=match.group(3)) line_info_extra=spaced_html_text(match.group(3), self.cfg))
if line[0] == '\\': if line[0] == '\\':
# \ No newline at end of file # \ No newline at end of file
@@ -2980,8 +2993,9 @@ def download_tarball(request):
def view_revision(request): def view_revision(request):
if request.roottype == "cvs": if request.roottype == "cvs":
raise ViewVCException("Revision view not supported for CVS repositories " raise debug.ViewVCException("Revision view not supported for CVS "
"at this time.", "400 Bad Request") "repositories at this time.",
"400 Bad Request")
data = common_template_data(request) data = common_template_data(request)
query_dict = request.query_dict query_dict = request.query_dict
@@ -3152,19 +3166,22 @@ def view_queryform(request):
data['query_action'], data['query_hidden_values'] = \ data['query_action'], data['query_hidden_values'] = \
request.get_form(view_func=view_query, params={'limit_changes': None}) request.get_form(view_func=view_query, params={'limit_changes': None})
def escaped_query_dict_get(itemname, itemdefault=''):
return request.server.escape(request.query_dict.get(itemname, itemdefault))
# default values ... # default values ...
data['branch'] = request.query_dict.get('branch', '') data['branch'] = escaped_query_dict_get('branch', '')
data['branch_match'] = request.query_dict.get('branch_match', 'exact') data['branch_match'] = escaped_query_dict_get('branch_match', 'exact')
data['dir'] = request.query_dict.get('dir', '') data['dir'] = escaped_query_dict_get('dir', '')
data['file'] = request.query_dict.get('file', '') data['file'] = escaped_query_dict_get('file', '')
data['file_match'] = request.query_dict.get('file_match', 'exact') data['file_match'] = escaped_query_dict_get('file_match', 'exact')
data['who'] = request.query_dict.get('who', '') data['who'] = escaped_query_dict_get('who', '')
data['who_match'] = request.query_dict.get('who_match', 'exact') data['who_match'] = escaped_query_dict_get('who_match', 'exact')
data['querysort'] = request.query_dict.get('querysort', 'date') data['querysort'] = escaped_query_dict_get('querysort', 'date')
data['date'] = request.query_dict.get('date', 'hours') data['date'] = escaped_query_dict_get('date', 'hours')
data['hours'] = request.query_dict.get('hours', '2') data['hours'] = escaped_query_dict_get('hours', '2')
data['mindate'] = request.query_dict.get('mindate', '') data['mindate'] = escaped_query_dict_get('mindate', '')
data['maxdate'] = request.query_dict.get('maxdate', '') data['maxdate'] = escaped_query_dict_get('maxdate', '')
data['limit_changes'] = int(request.query_dict.get('limit_changes', data['limit_changes'] = int(request.query_dict.get('limit_changes',
request.cfg.options.limit_changes)) request.cfg.options.limit_changes))
@@ -3394,27 +3411,29 @@ def build_commit(request, files, max_files, dir_strip, format):
return commit return commit
def query_backout(request, commits): def query_backout(request, commits):
request.server.header('text/plain') server_fp = get_writeready_server_file(request, 'text/plain')
if commits: if not commits:
print '# This page can be saved as a shell script and executed.' server_fp.write("""\
print '# It should be run at the top of your work area. It will update' # No changes were selected by the query.
print '# your working copy to back out the changes selected by the' # There is nothing to back out.
print '# query.' """)
print
else:
print '# No changes were selected by the query.'
print '# There is nothing to back out.'
return return
server_fp.write("""\
# This page can be saved as a shell script and executed.
# It should be run at the top of your work area. It will update
# your working copy to back out the changes selected by the
# query.
""")
for commit in commits: for commit in commits:
for fileinfo in commit.files: for fileinfo in commit.files:
if request.roottype == 'cvs': if request.roottype == 'cvs':
print 'cvs update -j %s -j %s %s/%s' \ server_fp.write('cvs update -j %s -j %s %s/%s\n'
% (fileinfo.rev, prev_rev(fileinfo.rev), % (fileinfo.rev, prev_rev(fileinfo.rev),
fileinfo.dir, fileinfo.file) fileinfo.dir, fileinfo.file))
elif request.roottype == 'svn': elif request.roottype == 'svn':
print 'svn merge -r %s:%s %s/%s' \ server_fp.write('svn merge -r %s:%s %s/%s\n'
% (fileinfo.rev, prev_rev(fileinfo.rev), % (fileinfo.rev, prev_rev(fileinfo.rev),
fileinfo.dir, fileinfo.file) fileinfo.dir, fileinfo.file))
def view_query(request): def view_query(request):
if not is_query_supported(request): if not is_query_supported(request):
@@ -3436,7 +3455,6 @@ def view_query(request):
mindate = request.query_dict.get('mindate', '') mindate = request.query_dict.get('mindate', '')
maxdate = request.query_dict.get('maxdate', '') maxdate = request.query_dict.get('maxdate', '')
format = request.query_dict.get('format') format = request.query_dict.get('format')
limit = int(request.query_dict.get('limit', 0))
limit_changes = int(request.query_dict.get('limit_changes', limit_changes = int(request.query_dict.get('limit_changes',
request.cfg.options.limit_changes)) request.cfg.options.limit_changes))
@@ -3503,16 +3521,17 @@ def view_query(request):
query.SetFromDateObject(mindate) query.SetFromDateObject(mindate)
if maxdate is not None: if maxdate is not None:
query.SetToDateObject(maxdate) query.SetToDateObject(maxdate)
if limit:
query.SetLimit(limit) # Set the admin-defined (via configuration) row limits. This is to avoid
elif format == 'rss': # slamming the database server with a monster query.
if format == 'rss':
query.SetLimit(request.cfg.cvsdb.rss_row_limit) query.SetLimit(request.cfg.cvsdb.rss_row_limit)
else:
query.SetLimit(request.cfg.cvsdb.row_limit)
# run the query # run the query
db.RunQuery(query) db.RunQuery(query)
sql = request.server.escape(db.CreateSQLQueryString(query))
# gather commits # gather commits
commits = [] commits = []
plus_count = 0 plus_count = 0
@@ -3596,7 +3615,7 @@ def view_query(request):
data = common_template_data(request) data = common_template_data(request)
data.update({ data.update({
'sql': sql, 'sql': request.server.escape(db.CreateSQLQueryString(query)),
'english_query': english_query(request), 'english_query': english_query(request),
'queryform_href': queryform_href, 'queryform_href': queryform_href,
'backout_href': backout_href, 'backout_href': backout_href,
@@ -3712,9 +3731,9 @@ def view_error(server, cfg):
exc_dict = debug.GetExceptionData() exc_dict = debug.GetExceptionData()
status = exc_dict['status'] status = exc_dict['status']
if exc_dict['msg']: if exc_dict['msg']:
exc_dict['msg'] = htmlify(exc_dict['msg']) exc_dict['msg'] = server.escape(exc_dict['msg'])
if exc_dict['stacktrace']: if exc_dict['stacktrace']:
exc_dict['stacktrace'] = htmlify(exc_dict['stacktrace']) exc_dict['stacktrace'] = server.escape(exc_dict['stacktrace'])
handled = 0 handled = 0
# use the configured error template if possible # use the configured error template if possible
@@ -3746,7 +3765,7 @@ def main(server, cfg):
finally: finally:
debug.t_end('main') debug.t_end('main')
debug.dump() debug.t_dump(server.file())
debug.DumpChildren(server) debug.DumpChildren(server)

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-python-*-
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -44,13 +44,11 @@ numbers, and not literal):
8. Update your working copy to HEAD, and tag the release: 8. Update your working copy to HEAD, and tag the release:
svn update svn up && svn cp -m "Tag the X.Y.Z final release." . ^/tags/X.Y.Z
svn cp -m "Tag the X.Y.Z final release." . \
http://viewvc.tigris.org/svn/viewvc/tags/X.Y.Z
9. Go into an empty directory and run the 'make-release' script: 9. Go into an empty directory and run the 'make-release' script:
tools/make-release viewvc-X.Y.Z X.Y.Z tools/make-release viewvc-X.Y.Z tags/X.Y.Z
10. Verify the archive files: 10. Verify the archive files:
@@ -79,7 +77,6 @@ numbers, and not literal):
(and possibly, minor or major) release. (For the Milestone sort (and possibly, minor or major) release. (For the Milestone sort
key, use a packed integer XXYYZZ: 1.0.3 == 10003, 2.11.4 == 21104.) key, use a packed integer XXYYZZ: 1.0.3 == 10003, 2.11.4 == 21104.)
15. Write an announcement explaining all the cool new features and 15. Send to the announce@ list a message explaining all the cool new
post it to the announce@ list, to the project's News area, and to features, and post similar announcements to other places interested
other places interested in this sort of stuff, such as Freshmeat in this sort of stuff, such as Freshmeat (http://www.freshmeat.net).
(http://www.freshmeat.net).

View File

@@ -4,22 +4,30 @@
<thead> <thead>
<tr> <tr>
<th class="vc_header[is sortby "file"]_sort[end]" colspan="2"> <th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
<a href="[sortby_file_href]#dirlist">File [if-any sortby_file_href]<a href="[sortby_file_href]#dirlist">File</a>[else]File[end]
[is sortby "file"] [is sortby "file"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
[if-any sortby_rev_href]
<th class="vc_header[is sortby "rev"]_sort[end]"> <th class="vc_header[is sortby "rev"]_sort[end]">
<a href="[sortby_rev_href]#dirlist">Last Change <a href="[sortby_rev_href]#dirlist">Last Change</a>
[is sortby "rev"] [is sortby "rev"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a> [else]
<th class="vc_header[is sortby "date"]_sort[end]">
[if-any sortby_date_href]<a href="[sortby_date_href]#dirlist">Last Change</a>[else]Last Change[end]
[is sortby "date"]
<img class="vc_sortarrow" alt="[is sortdir "down"](date)[end]"
width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end]
[end]
</th> </th>
</tr> </tr>
</thead> </thead>

View File

@@ -4,50 +4,45 @@
<thead> <thead>
<tr> <tr>
<th class="vc_header[is sortby "file"]_sort[end]" colspan="2"> <th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
<a href="[sortby_file_href]#dirlist">File [if-any sortby_file_href]<a href="[sortby_file_href]#dirlist">File</a>[else]File[end]
[is sortby "file"] [is sortby "file"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
<th class="vc_header[is sortby "rev"]_sort[end]"> <th class="vc_header[is sortby "rev"]_sort[end]">
<a href="[sortby_rev_href]#dirlist">Rev. [if-any sortby_rev_href]<a href="[sortby_rev_href]#dirlist">Rev.</a>[else]Rev.[end]
[is sortby "rev"] [is sortby "rev"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
<th class="vc_header[is sortby "date"]_sort[end]"> <th class="vc_header[is sortby "date"]_sort[end]">
<a href="[sortby_date_href]#dirlist">Age [if-any sortby_date_href]<a href="[sortby_date_href]#dirlist">Age</a>[else]Age[end]
[is sortby "date"] [is sortby "date"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
<th class="vc_header[is sortby "author"]_sort[end]"> <th class="vc_header[is sortby "author"]_sort[end]">
<a href="[sortby_author_href]#dirlist">Author [if-any sortby_author_href]<a href="[sortby_author_href]#dirlist">Author</a>[else]Author[end]
[is sortby "author"] [is sortby "author"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
[is cfg.options.show_logs "1"] [is cfg.options.show_logs "1"]
<th class="vc_header[is sortby "log"]_sort[end]"> <th class="vc_header[is sortby "log"]_sort[end]">
<a href="[sortby_log_href]#dirlist">Last log entry [if-any sortby_log_href]<a href="[sortby_log_href]#dirlist">Last log entry</a>[else]Last log entry[end]
[is sortby "log"] [is sortby "log"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]" <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13" width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" /> src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end] [end]
</a>
</th> </th>
[end] [end]
</tr> </tr>

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -17,17 +17,18 @@
### Validate input ### Validate input
if test $# != 2 && test $# != 1; then if test $# != 2 && test $# != 1; then
echo "Usage: $0 TARGET-DIRECTORY [TAGNAME]" echo "Usage: $0 TARGET-DIRECTORY [BRANCH]"
echo "" echo ""
echo "If TAGNAME is not provided, the release will be rolled from trunk." echo "If BRANCH (i.e. \"tags/1.1.0\" or \"branches/1.0.x\") is not provided,"
echo "the release will be rolled from trunk."
exit 1 exit 1
fi fi
TARGET=${1} TARGET=${1}
if test $# == 1; then if test $# = 1; then
ROOT=trunk ROOT=trunk
else else
ROOT=tags/${2} ROOT=${2}
fi fi
if test -e ${TARGET}; then if test -e ${TARGET}; then
@@ -36,7 +37,8 @@ if test -e ${TARGET}; then
fi fi
### Grab an export from the Subversion repository. ### Grab an export from the Subversion repository.
echo "Exporting into:" ${TARGET} EXPORT_URL="http://viewvc.tigris.org/svn/viewvc/${ROOT}"
echo "Exporting '${EXPORT_URL}' into '${TARGET}'"
for PLATFORM in unix windows; do for PLATFORM in unix windows; do
if test ${PLATFORM} = windows; then if test ${PLATFORM} = windows; then
@@ -48,7 +50,7 @@ for PLATFORM in unix windows; do
echo "Beginning build for ${PLATFORM}:" echo "Beginning build for ${PLATFORM}:"
echo " Exporting source code..." echo " Exporting source code..."
svn export --quiet ${EOL} http://viewvc.tigris.org/svn/viewvc/${ROOT} ${TARGET} svn export --quiet ${EOL} ${EXPORT_URL} ${TARGET}
### Various shifting, cleanup. ### Various shifting, cleanup.

View File

@@ -1,5 +1,5 @@
/* /*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/* /*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/* /*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/* /*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- Mode: python -*- # -*- Mode: python -*-
# #
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. # Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,2 +0,0 @@
*.tar.gz
*.zip

View File

@@ -1,68 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>ViewVC: Contact</title>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="./index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="./download.html">Download</a> |
<a href="./upgrading.html">Upgrading</a> |
<a href="./contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="./contact.html">Contact</a> |
<a href="./who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-contacting-us">Contacting Us</a></li>
</ul>
<hr/>
<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-contacting-us">Contacting Us</h2>
<p>Please send any comments, questions, or suggestions to the <a
href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC users mailing
list</a>. There is also a <a
href="mailto:&#100&#101&#118&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">mailing list specifically for
ViewVC developers</a>. You can subscribe to these lists, as well
view the list archives, (and other
project lists) <a
href="http://viewvc.tigris.org/servlets/ProjectMailingListList"
>here</a>.</p>
<p>ViewVC is an <a href="http://www.opensource.org/">Open
Source</a> project, and all <a href="./contributing.html">contributions</a>
are welcome.</p>
</div>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,276 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>ViewVC: Contributing</title>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="./index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="./download.html">Download</a> |
<a href="./upgrading.html">Upgrading</a> |
<a href="./contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="./contact.html">Contact</a> |
<a href="./who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-getting-started">Getting Started</a></li>
<li><a href="#sec-testing">Testing and Reporting</a></li>
<li><a href="#sec-coding-style">Coding Style</a></li>
<li><a href="#sec-patches">Submitting Patches</a></li>
<li><a href="#sec-security">Security</a></li>
<li><a href="#sec-adding-features">Adding Features</a></li>
<li><a href="#sec-templates">Hacking on Templates</a></li>
<li><a href="#sec-releasing">Release Management</a></li>
</ul>
<hr/>
<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-getting-started">Getting Started</h2>
<p>Some basic knowledge about <a
href="http://www.python.org">Python</a> and development tools like
<code>diff</code> is required. Your best bet is to start with a
fresh source code snapshot, which you may obtain from our
Subversion repository (see instructions <a
href="./download.html#sec-subversion">here</a>).</p>
<p>Version control history can be obtained using Subversion clients,
but is also browsable using <a
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/"
>tigris.org's integrated ViewVC tool</a>.</p>
</div>
<div class="section">
<h2 id="sec-testing">Testing and Reporting</h2>
<p>Testing usability and the installation process on different
platforms is also a valuable contribution. Please report your
results back to us developers. Bandwidth is getting cheaper daily,
so don't be afraid &mdash; in fact, feel encouraged &mdash; to dump
as much detail about the problems you are seeing as possible into
your bug reports. Here are some things you definitely should
try to include:</p>
<ul>
<li>What version of ViewVC you are using (if you are using a source
snapshot, tell us the date of that snapshot).</li>
<li>What operating system your ViewVC is running on.</li>
<li>What version of Python you are using.</li>
<li>Whether you are running ViewVC standalone, or as a CGI program
under a web server (and if so, what web server).</li>
<li>The URL of your ViewVC instantiation, if it is public.
Sometimes, letting developers see the problem for themselves can
save everyone alot of time.</li>
</ul>
</div>
<div class="section">
<h2 id="sec-coding-style">Coding Style</h2>
<p>Unlike its predecessor, CvsWeb, ViewVC is written in Python, so it
doesn't suffer from the "unmaintainable code effect" that hits most
Perl projects sooner or later:</p>
<blockquote><em>&quot;[Perl] combines all the worst aspects of C and Lisp: a
billion different sublanguages in one monolithic executable. It
combines the power of C with the readability of PostScript.&quot;</em>
&mdash;&nbsp;Jamie&nbsp;Zawinski
</blockquote>
<p>Of course, a symphony of insanity can be composed in any language,
so we do try to stick to some basic guiding principles. Maintain
whatever style is present in the code being modified. New code can
use anything sane (which generally means <a
href="http://python.sourceforge.net/peps/pep-0008.html">PEP&nbsp;8</a>).
Our only real peeve is if someone writes a function call as:
<code>some_func&nbsp;(args)</code> &mdash; that space between the
function name and opening parenthesis is Huge Badness. Oh, and we
do <strong>not</strong> use Subversion keywords (such as
<code>$</code><code>Id$</code>) within the source.</p>
<p>Otherwise&hellip; <em>shrug</em>.</p>
</div>
<div class="section">
<h2 id="sec-patches">Submitting Patches</h2>
<p>Nothing speaks more loudly when bugs or features are the topic than
a patch. And quite frankly, sometimes if you want something done,
you gotta do it yourself. So, patches are always welcome. If you
aren't sure what exactly a &quot;patch&quot; is, or don't know how
to generate one, but you've got code contributions to make, please
don't hesitate to ask questions on the mailing lists. Patch
generation and application are pretty easy thing to get the hang of,
and drastically simplify code submission and review.</p>
<p>Please use the <a
href="http://viewvc.tigris.org/servlets/ProjectIssues">Issue
Tracker</a> to submit your patches. Unified contextual diffs
against the latest development snapshot are preferred.</p>
<p>If you have commit access, then you should know what you're doing.
Just make changes directly. Subscribing to the <a
href="http://viewvc.tigris.org/servlets/ProjectMailingListList"
><tt>dev@</tt> developer mailing list</a> is recommended in any
case.</p>
</div>
<div class="section">
<h2 id="sec-security">Security</h2>
<p>Since ViewVC is used on the Internet, security is a major concern.
If you need to pass data from the request into an external program,
please don't use <code>os.system()</code> or
<code>os.popen()</code>. Please use the module
<code>lib/popen.py</code> that is included in the ViewVC
distribution instead.</p>
</div>
<div class="section">
<h2 id="sec-adding-features">Adding Features</h2>
<p>If you need a new configuration option think carefully, into which
section it belongs. Try to keep the content of
<code>cgi/viewvc.conf.dist</code> file and the library module
<code>lib/config.py</code> in sync.</p>
<p>Because ViewVC is a Web-based application, people will have ViewVC
URLs hyperlinked from other sites, embedded in emails, bookmarked
in their browsers, etc. It is very important to ensure that those
URLs continue to retrieve the information they were intended to
retrieve even if ViewVC is upgraded on the hosting server. In
other words, as new features require modifications to the <a
href="./url-reference.html">ViewVC URL schema</a>, make sure those
modifications preserve the existing functionality of all ViewVC
URLs.</p>
<p>The library subdirectory contains a module <code>debug.py</code>,
which you may find useful for performance testing.</p>
<p>If a new file or module is added, a new line in the installer
program <code>viewvc-install</code> is required.</p>
</div>
<div class="section">
<h2 id="sec-templates">Hacking on Templates</h2>
<p>The library module <code>ezt.py</code> contains a module docstring
which describes the directives used in the HTML templates used by
ViewVC. The templates themselves can be found in the
<code>templates</code> subdirectory. We're currently developing a
how-to guide for <a href="./template-authoring-guide.html">ViewVC
template customization</a>.</p>
</div>
<div class="section">
<h2 id="sec-releasing">Release Management</h2>
<p>There is a script, <code>tools/make-release</code>, which creates a
release directory and the various archive files that we distribute.
All other steps required to get a ViewVC release out of the door
require manual execution (currently by C. Michael Pilato). Those
steps are as follows:</p>
<ol>
<li>Add a new subsection to the file
<code>website/upgrading.html</code> describing all user visible
changes for users of previous releases of ViewVC.</li>
<li>Update the <code>CHANGES</code> file</li>
<li>Update the <code>website/index.html</code> file to refer to the
new X.Y files. (there are three links to update)</li>
<li>Edit the file <code>lib/viewvc.py</code> and remove the
<tt>"-dev"</tt> suffix from <code>__version__</code>. The
remainder should be of the form X.Y.Z, where X, Y, and Z are
positive integers.</li>
<li>Ensure all of the above changes have been committed.</li>
<li>Test, Test, Test! At the time of this writing (1.0-dev) there
is no automatic testsuite available. So just run with
permuting different <code>viewvc.conf</code> settings&hellip;
and pray.</li>
<li>Review any open <a
href="http://viewvc.tigris.org/servlets/ProjectIssues">bug
reports.</a></li>
<li>Use <code>svn cp</code> to tag the release to
<code>/tags/<i>X</i>.<i>Y</i>.<i>Z</i></code>, where
<i>X</i>, <i>Y</i>, and <i>Z</i> should be replaced by the
release number from above. If a developer is willing to
volunteer as a bug fix patch release manager, it is now
possible to start here at this point with a feature-frozen
branch using <code>svn cp</code> to copy the tag to
<code>/branches/<i>X</i>.<i>Y</i>.x</code>.</li>
<li>Go into an empty directory and run <code>tools/make-release
viewvc-<i>X.Y.Z</i> <i>X.Y.Z</i></code>. This step requires
read access to the Subversion source code repository.</li>
<li>Upload the created archive files (tar.gz and zip) into the
Files and Documents section of the Tigris.org project.</li>
<li>Edit the file <code>lib/viewvc.py</code> again and this time
increment the <code>__version__</code> for the next release
cycle, again append the <code>-dev</code> to the version and
again <code>svn commit -m "Begin a new release cycle."
lib/viewvc.py</code>.</li>
<li>Write an announcement explaining all the cool new features and
post it <a
href="mailto:&#97&#110&#110&#111&#117&#110&#99&#101&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">&#97&#110&#110&#111&#117&#110&#99&#101&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103</a>,
to the project's News area, and to other places interested in
this sort of stuff (such as <a
href="http://www.freshmeat.net">Freshmeat</a>).</p>
</ol>
</div>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,79 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>ViewVC: Download</title>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="./index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="./download.html">Download</a> |
<a href="./upgrading.html">Upgrading</a> |
<a href="./contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="./contact.html">Contact</a> |
<a href="./who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-download">Downloading</a></li>
<li><a href="#sec-subversion">Subversion</a></li>
</ul>
<hr/>
<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-download">Downloading</h2>
<p>You can download the ViewVC (and the older ViewCVS releases, too)
from our <a
href="http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004"
>File and Documents</a> area. For information about what has
changed in each release, see the <a
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
>CHANGES</a> file.</p>
<p>We are also making <a href="./nightly/">nightly snapshots</a>
available in tar.gz and zip formats.</p>
</div>
<div class="section">
<h2 id="sec-subversion">Subversion</h2>
<p>The source code for ViewVC is maintained in a Subversion repository
at Tigris.org. You can checkout the trunk of our development tree
from <a href="http://viewvc.tigris.org/svn/viewvc/trunk/"
><tt>http://viewvc.tigris.org/svn/viewvc/trunk/</tt></a>. You'll
need to provide your Tigris.org username and password when so
prompted, or, if you don't have a Tigris.org account, use "guest"
as both the username and password.</p>
</div>
</td>
</tr>
</table>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

View File

@@ -1,192 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>ViewVC: Repository Browsing</title>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="./index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="./download.html">Download</a> |
<a href="./upgrading.html">Upgrading</a> |
<a href="./contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="./contact.html">Contact</a> |
<a href="./who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-what-is-viewvc">What Is ViewVC?</a></li>
<li><a href="#sec-requirements">Requirements</a></li>
<li><a href="#sec-future">Future Plans</a></li>
</ul>
<hr/>
<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-what-is-viewvc">What Is ViewVC?</h2>
<p>ViewVC is a browser interface for CVS and Subversion version
control repositories. It generates templatized HTML to present
navigable directory, revision, and change log listings. It can
display specific versions of files as well as diffs between those
versions. Basically, ViewVC provides the bulk of the report-like
functionality you expect out of your version control tool, but much
more prettily than the average textual command-line program
output.</p>
<p>Here are some of the additional features of ViewVC:</p>
<ul>
<li>Support for filesystem-accessible CVS and Subversion repositories.</li>
<li>Individually configurable virtual host support.</li>
<li>Line-based annotation/blame display.</li>
<li>Revision graph capabilities (via integration with <a
href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>)
(<em>CVS only</em>).</li>
<li>Syntax highlighting support (via integration with <a
href="http://www.codento.com/people/mtr/genscript/">GNU
enscript</a> or
<a href="http://www.andre-simon.de/">Highlight</a>).</li>
<li><a href="http://www.mozilla.org/projects/bonsai/">Bonsai</a>-like
repository query facilities.</li>
<li>Template-driven output generation.</li>
<li>Colorized, side-by-side differences.</li>
<li>Tarball generation (by tag/branch for CVS, by revision for
Subversion).</li>
<li>I18N support based on the Accept-Language request header.</li>
<li>Ability to run either as CGI script or as a standalone
server.</li>
<li>Regexp-based file searching.</li>
<li>INI-like configuration file (as opposed to requiring actual code
tweaks).</li>
</ul>
<p>For a complete list of changes present in each release, see
ViewVC's <a
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
>CHANGES</a> file.</p>
</div>
<div class="section">
<h2 id="sec-requirements">Requirements</h2>
<p>The only hard software requirement for running ViewVC is <a
href="http://www.python.org/">Python 1.5.2</a> or later. All other
requirements depend on what you want to do with the tool.</p>
<p>If you plan to use ViewVC with CVS repositories, you need the
following things:</p>
<ul>
<li><a href="http://www.cs.purdue.edu/homes/trinkle/RCS/">RCS</a>
(Revision Control System)</li>
<li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU
diff</a></li>
<li>Read-only, physical access to a CVS repository.</li>
</ul>
<p>For use with Subversion repositories, you need these things:</p>
<ul>
<li><a href="http://subversion.tigris.org/">Subversion</a> 1.2 or
later and its SWIG Python bindings.</li>
<li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU
diff</a></li>
<li>Physical access to a Subversion repository (though there is
limited, use-at-your-risk support for remote access, too).</li>
</ul>
<p>ViewVC integrates with additional pieces of software to provide
certain bits of optional functionality:</p>
<ul>
<li><a href="http://www.mysql.com/">MySQL</a> &mdash; Needed to use
the commit database query functionality.</li>
<li><a href="http://www.codento.com/people/mtr/genscript/">GNU
enscript</a> &mdash; Needed for syntax highlighting in versioned
file contents displays</li>
<li><a href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>
&mdash; Needed for version graph displays.</li>
<li><a href="http://httpd.apache.org/">Apache HTTP Server</a>, or
another server capable of running CGI programs &mdash; unless
you just want ViewVC to run in standalone server mode.</li>
</ul>
</div>
<div class="section">
<h2 id="sec-future">Future Plans</h2>
<p>ViewVC is an Open Source project. So any future development
depends on the <a href="./contributing.html">contributions</a> that
will be made by its user community. Certainly working patches have
a greater chance to become realized quickly than feature requests,
but please don't hesitate to submit your suggestions to our <a
href="http://viewvc.tigris.org/servlets/ProjectIssues">issue
tracker</a>.</p>
<p>Some things we're thinking about include:</p>
<ul>
<li>UI streamlining/simplification.</li>
<li>Integration with CVS and Subversion commit mail scripts.</li>
<li>Integration with an indexer such as LXR.</li>
</ul>
</div>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,95 +0,0 @@
#!/bin/sh
DATE=`date +"%Y%m%d"`
EXPORTDIR="viewvc-${DATE}"
PUBLISH_DIR=/www/viewvc/nightly
# export HEAD of trunk
svn export --quiet http://viewvc.tigris.org/svn/viewvc/trunk ${EXPORTDIR} --username guest --password ""
# use Python to determine the version number, reading it from
# viewvc.__version__
cd $EXPORTDIR/lib
VERSION=`python -c "import viewvc; print viewvc.__version__"`
TARGET=viewvc-${VERSION}-${DATE}
# make a release
cd ../tools
./make-release ${TARGET}
# remove results of last build
rm -rf ${PUBLISH_DIR}/viewvc*.tar.gz ${PUBLISH_DIR}/viewvc*.zip ${PUBLISH_DIR}/index.html
# publish new build
mv ${TARGET}.* ${PUBLISH_DIR}
cd ../..
cat > ${PUBLISH_DIR}/index.html <<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>ViewVC: Nightly Snapshots</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="../styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="../images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="../index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="../download.html">Download</a> |
<a href="../contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="../contact.html">Contact</a> |
<a href="../who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-snapshots">Snapshots</a></li>
</ul>
<p><a href="http://validator.w3.org/check?uri=referer"><img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
</p>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-snapshots">Snapshots</h2>
<ul>
EOF
echo "<li><a href=\"${TARGET}.tar.gz\">${TARGET}.tar.gz</a></li>" >> ${PUBLISH_DIR}/index.html
echo "<li><a href=\"${TARGET}.zip\">${TARGET}.zip</a></li>" >> ${PUBLISH_DIR}/index.html
cat >> ${PUBLISH_DIR}/index.html <<EOF
</ul>
</div>
</td>
</tr>
</table>
</body>
</html>
EOF
# more cleanup
rm -rf ${EXPORTDIR}

View File

@@ -1,151 +0,0 @@
body {
background-color: rgb(180,193,205);
background-image: url('./images/bg-grad.jpg');
background-repeat: repeat-x;
color: black;
font-family: arial, sans-serif;
font-size: 90%;
margin: 0;
}
#title {
background-color: rgb(100,128,150);
height: 60px;
}
img {
border: none;
}
hr {
width: 95%;
height: 1px;
}
address {
text-align: center;
font-size: 60%;
font-style: normal;
}
h2 {
background-color: rgb(204,213,221);
padding: 2px 0.5em 2px 0.5em;
margin: 0;
border-bottom: dotted 1px rgb(180,193,205);
font-size: 110%;
}
h3 {
padding: 2px 0.5em 2px 0.5em;
margin: 0;
font-size: 100%;
font-weight: bold;
}
h4 {
padding: 2px 0.5em 2px 0.5em;
margin: 0;
font-size: 90%;
font-weight: bold;
}
p, dl, ul, ol {
padding: 0.5em;
margin: 0;
font-size: 90%;
}
ul, ol {
padding: 0.5em;
margin: 0 0 0 0.25in;
}
li {
font-size: 90%;
}
code {
font-size: 105%;
font-style: italic;
font-family: monospace;
}
blockquote {
padding: 0.5em;
margin: 0 0.25in 0 0.25in;
font-size: 80%;
}
.section {
background: white;
border-color: rgb(24,24,24);
border-width: 1px 2px 2px 1px;
border-style: solid;
padding: 0;
margin-bottom: 0.5em;
}
#menu {
background: black;
color: white;
}
#menu a, #menu a:visited {
background: black;
color: white;
text-decoration: none;
}
#menu a:hover {
background: black;
color: white;
text-decoration: underline;
}
#submenu {
background: rgb(90%,97%,99%);
font-size: 80%;
}
#pagetable tr {
vertical-align: top;
}
#pagetable {
width: 100%;
}
#pagecolumn1 {
width: 175px;
padding: 0;
}
#pagecolumn1 a, #pagecolumn1 a:visited {
color: rgb(0,0,164);
text-decoration: none;
}
#pagecolumn1 a:hover {
text-decoration: underline;
}
#pagecolumn2 {
padding: 0;
}
#pagecolumn2 a, #pagecolumn2 a:visited {
color: rgb(0,0,164);
text-decoration: underline;
}
#pagecolumn2 a:hover {
background-color: rgb(180,193,205);
text-decoration: underline;
}
#bookmarks {
padding-left: 0.25in;
font-size: 80%;
white-space: nowrap;
}

View File

@@ -1,159 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>ViewVC: About</title>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
</head>
<body>
<div id="title">
<a href="http://www.viewvc.org/"><img
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
</div>
<div id="menu">
<p><a href="./index.html">Home</a> |
<a href="http://viewvc.tigris.org/">Project Page</a> |
<a href="./download.html">Download</a> |
<a href="./upgrading.html">Upgrading</a> |
<a href="./contributing.html">Contributing</a> |
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
<a href="./contact.html">Contact</a> |
<a href="./who.html">About</a>
</p>
</div>
<table id="pagetable">
<tr>
<td id="pagecolumn1">
<h4>On this page:</h4>
<ul id="bookmarks">
<li><a href="#sec-history">The History of ViewVC</a></li>
<li><a href="#sec-viewcvs-group">The ViewCVS Group</a></li>
<li><a href="#sec-site-credits">About This Site</a></li>
</ul>
<hr/>
<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
</td>
<td id="pagecolumn2">
<div class="section">
<h2 id="sec-history">The History of ViewVC</h2>
<p>The ViewVC software was inspired by <a
href="http://people.freebsd.org/~fenner/cvsweb/">cvsweb</a>
(originally written by Bill Fenner and then further developed by <a
href="mailto:zeller@think.de">Henner Zeller</a>). Greg Stein
wanted to make some changes and updates, but cvsweb was implemented
in Perl. He wrote:</p>
<blockquote style="font-style: italic;">&quot;While I can manage some
Perl, cvsweb was rather unmaintainable for me. So I undertook the
task to convert the software to Python. As a result, I've actually
been able to go <em>way</em> beyond the simple changes that I had
envisioned.&quot;</blockquote>
<p>So ViewVC started out as just a port of the cvsweb script,
originally called ViewCVS. Along the way, it has had numerous
cleanups and other modifications, a process simplified by the
elegance of the <a href="http://www.python.org/">Python</a>
language.</p>
<p>In 2001, the ViewCVS project was moved to <a
href="http://www.sourceforge.net">SourceForge</a>, a popular
software collaboration environment. There the project continued to
mature, releasing several stable-yet-pre-1.0 versions. In 2002,
C. Michael Pilato began implementing support for Subversion in
ViewCVS, building atop the beginnings of a version control
abstraction layer begun by Lucas Bruand. Along the way, Russell
Yanofsky delivered large improvements to that abstraction, and to
ViewCVS as whole. ViewCVS was well on its way to releasing a 1.0
version.</p>
<p>Of course, now that ViewCVS could browse Subversion repositories as
easily as CVS ones, the ViewCVS name seemed inappropriate. Also,
SourceForge's lack of support for Subversion (which was already
well past its 1.0 release, and becoming hugely popular) in its
project version control offerings was annoying ViewCVS primary
developers. So in late 2005, the decision was made to rename the
project to ViewVC, to convert the project's CVS data to Subversion,
and to move the project and its Subversion data to <a
href="http://www.tigris.org">Tigris.org</a>.</p>
<p>Today, ViewVC is being developed at <a
href="http://viewvc.tigris.org">http://viewvc.tigris.org</a> by a
small community of folks</a>.</p>
</div>
<div class="section">
<h2 id="sec-viewcvs-group">The ViewCVS Group</h2>
<p>The ViewCVS Group is an informal group of people working on and
developing the ViewVC package. The current set of members are
listed below with some of their notable contributions:</p>
<dl>
<dt><a href="http://www.lyra.org/greg/">Greg Stein</a></dt>
<dd>original python port of Henner Zeller's cvsweb, secure popen
implementation, configuration file implementation, rcsparse
module, and EZT template engine</dd>
<dt>Jay Painter</dt>
<dd>CVSdb query engine</dd>
<dt>Tanaka Akira</dt>
<dd>enscript colorization and tarball generation
</dd>
<dt>Tim Cera</dt>
<dd>CvsGraph support, log_table template, regular expression search,
and paging capability</dd>
<dt>Peter Funk</dt>
<dd>standalone server, blimp logo, and numerous improvements to
ViewVC's interfaces and documentation</dd>
<dt>Lucas Bruand</dt>
<dd>C++ RCS parser (tparse) and vclib module for supporting new
version control systems</dd>
<dt><a href="http://www.cmichaelpilato.com/">C. Michael Pilato</a></dt>
<dd>Subversion support, root_as_url alternative URL scheme,
templatization work, website design, documentation</dd>
<dt>Russell Yanofsky</dt>
<dd>Windows support and the sapi module for supporting multiple web
server interfaces, sweeping abstraction and UI improvements</dd>
<dt>James Henstridge</dt>
<dd>integrated query interface, support for querying Subversion
repositories, caching support, CSS formatting, and the EZT
&quot;define&quot; directive</dd>
</dl>
</div>
<div class="section">
<h2 id="sec-site-credits">About This Site</h2>
<p>The ViewVC website was designed by <a
href="http://www.cmichaelpilato.com/">C. Michael Pilato</a>. All
HTML was hand-edited in Emacs, and the little splashes of graphical
goodness owe their existence to Adobe PhotoShop. Textual content
for the site is mostly the work of Greg Stein, but has been tweaked
through the ages by various ViewVC contributors.</p>
</div>
</td>
</tr>
</table>
</body>
</html>