]> git.saurik.com Git - wxWidgets.git/blob - src/common/fs_inet.cpp
Fixed some potential buffer overruns
[wxWidgets.git] / src / common / fs_inet.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: fs_inet.cpp
3 // Purpose: HTTP and FTP file system
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
10 #pragma implementation "fs_inet.h"
11 #endif
12
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if !wxUSE_SOCKETS
20 #undef wxUSE_FS_INET
21 #define wxUSE_FS_INET 0
22 #endif
23
24 #if wxUSE_FILESYSTEM && wxUSE_FS_INET
25
26 #ifndef WXPRECOMP
27 #endif
28
29 #include "wx/wfstream.h"
30 #include "wx/url.h"
31 #include "wx/filesys.h"
32 #include "wx/fs_inet.h"
33 #include "wx/module.h"
34
35 // ----------------------------------------------------------------------------
36 // Helper classes
37 // ----------------------------------------------------------------------------
38
39 // This stream deletes the file when destroyed
40 class wxTemporaryFileInputStream : public wxFileInputStream
41 {
42 public:
43 wxTemporaryFileInputStream(const wxString& filename) :
44 wxFileInputStream(filename), m_filename(filename) {}
45
46 ~wxTemporaryFileInputStream()
47 {
48 // NB: copied from wxFileInputStream dtor, we need to do it before
49 // wxRemoveFile
50 if (m_file_destroy)
51 {
52 delete m_file;
53 m_file_destroy = false;
54 }
55 wxRemoveFile(m_filename);
56 }
57
58 protected:
59 wxString m_filename;
60 };
61
62
63 // ----------------------------------------------------------------------------
64 // wxInternetFSHandler
65 // ----------------------------------------------------------------------------
66
67 static wxString StripProtocolAnchor(const wxString& location)
68 {
69 wxString myloc(location.BeforeLast(wxT('#')));
70 if (myloc.IsEmpty()) myloc = location.AfterFirst(wxT(':'));
71 else myloc = myloc.AfterFirst(wxT(':'));
72
73 // fix malformed url:
74 if (myloc.Left(2) != wxT("//"))
75 {
76 if (myloc.GetChar(0) != wxT('/')) myloc = wxT("//") + myloc;
77 else myloc = wxT("/") + myloc;
78 }
79 if (myloc.Mid(2).Find(wxT('/')) == wxNOT_FOUND) myloc << wxT('/');
80
81 return myloc;
82 }
83
84
85 bool wxInternetFSHandler::CanOpen(const wxString& location)
86 {
87 #if wxUSE_URL
88 wxString p = GetProtocol(location);
89 if ((p == wxT("http")) || (p == wxT("ftp")))
90 {
91 wxURL url(p + wxT(":") + StripProtocolAnchor(location));
92 return (url.GetError() == wxURL_NOERR);
93 }
94 #endif
95 return false;
96 }
97
98
99 wxFSFile* wxInternetFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs),
100 const wxString& location)
101 {
102 #if !wxUSE_URL
103 return NULL;
104 #else
105 wxString right =
106 GetProtocol(location) + wxT(":") + StripProtocolAnchor(location);
107
108 wxURL url(right);
109 if (url.GetError() == wxURL_NOERR)
110 {
111 wxInputStream *s = url.GetInputStream();
112 wxString content = url.GetProtocol().GetContentType();
113 if (content == wxEmptyString) content = GetMimeTypeFromExt(location);
114 if (s)
115 {
116 wxString tmpfile =
117 wxFileName::CreateTempFileName(wxT("wxhtml"));
118
119 { // now copy streams content to temporary file:
120 wxFileOutputStream sout(tmpfile);
121 s->Read(sout);
122 }
123 delete s;
124
125 return new wxFSFile(new wxTemporaryFileInputStream(tmpfile),
126 right,
127 content,
128 GetAnchor(location)
129 #if wxUSE_DATETIME
130 , wxDateTime::Now()
131 #endif // wxUSE_DATETIME
132 );
133 }
134 }
135
136 return (wxFSFile*) NULL; // incorrect URL
137 #endif
138 }
139
140
141 class wxFileSystemInternetModule : public wxModule
142 {
143 DECLARE_DYNAMIC_CLASS(wxFileSystemInternetModule)
144
145 public:
146 virtual bool OnInit()
147 {
148 wxFileSystem::AddHandler(new wxInternetFSHandler);
149 return true;
150 }
151 virtual void OnExit() {}
152 };
153
154 IMPLEMENT_DYNAMIC_CLASS(wxFileSystemInternetModule, wxModule)
155
156 #endif // wxUSE_FILESYSTEM && wxUSE_FS_INET