• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

The MinGW.org Installation Manager Tool


Commit MetaInfo

Revision20b1d629e6b23539de8e55151f30e10b2238b803 (tree)
Zeit2013-09-10 19:00:20
AutorKeith Marshall <keithmarshall@user...>
CommiterKeith Marshall

Log Message

Fix MinGW-Bug #2026.

Ändern Zusammenfassung

Diff

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
1+2013-09-10 Keith Marshall <keithmarshall@users.sourceforge.net>
2+
3+ Fix MinGW-Bug #2026.
4+
5+ * src/dmhguix.cpp (DMH_PTY_GUARDBYTES): New manifest constant.
6+ (dmhTypePTY::printf) [buffer full]: Use it; it defines a reserved byte
7+ count, at end of buffer, where expansion or scroll out is triggered;
8+ use memcpy() for scroll out, but avoid overlapping regions.
9+ (dmhTypePTY::printf) [output == '\r']: Handle it.
10+
11+ * src/tarproc.cpp (create_output_stream): Improve diagnostic messages;
12+ discriminate between file collision and other privilege violations.
13+ (pkgArchiveProcessor::ExtractFile): Don't return a zero status code,
14+ when the output stream could not be successfully opened, so that...
15+ (pkgTarArchiveInstaller::ProcessDataStream): ...we may avoid writing a
16+ spurious manifest entry here.
17+
118 2013-09-06 Keith Marshall <keithmarshall@users.sourceforge.net>
219
320 Update version, pre-empting subsequent release.
--- a/src/dmhguix.cpp
+++ b/src/dmhguix.cpp
@@ -40,6 +40,7 @@
4040 */
4141 #define DMH_PTY_MIN_BUFSIZ 4096
4242 #define DMH_PTY_MAX_BUFSIZ 32768
43+#define DMH_PTY_GUARDBYTES 1
4344
4445 class dmhTypePTY
4546 {
@@ -142,10 +143,14 @@ int dmhTypePTY::printf( const char *fmt, va_list argv )
142143 {
143144 /* An explicit '\r' in the data stream should return the
144145 * caret to the start of the current PHYSICAL line in the
145- * EDITTEXT display
146- *
147- * FIXME: must implement this; ignore, (and discount), it
148- * for now.
146+ * EDITTEXT display.
147+ */
148+ char *mark = caret;
149+ while( (mark > console_buffer) && (*--mark != '\n') )
150+ caret = mark;
151+
152+ /* The '\r' character isn't actually written to the
153+ * output buffer; discount it.
149154 */
150155 --retval;
151156 }
@@ -187,10 +192,12 @@ int dmhTypePTY::putchar( int charval )
187192 {
188193 /* Helper method for appending a single character to the PTY "device"
189194 * buffer; this will allocate an expanding buffer, (up to the maximum
190- * specified size limit), as may be required.
195+ * specified size limit, with reservation of sufficient guard bytes to
196+ * ensure that output may be safely terminated), as may be required.
191197 */
192198 size_t offset;
193- if( (offset = caret - console_buffer) >= max )
199+ const size_t guarded_max = max - DMH_PTY_GUARDBYTES;
200+ if( (offset = caret - console_buffer) >= guarded_max )
194201 {
195202 /* The current "device" buffer is full; compute a new size, for
196203 * possible buffer expansion.
@@ -215,7 +222,7 @@ int dmhTypePTY::putchar( int charval )
215222 caret = (console_buffer = newbuf) + offset;
216223 }
217224 }
218- if( offset >= max )
225+ if( offset >= guarded_max )
219226 {
220227 /* The buffer has reached its maximum permitted size, (or there
221228 * was insufficient free memory to expand it), and there still
@@ -228,9 +235,34 @@ int dmhTypePTY::putchar( int charval )
228235 /* ...then copy it, and all following lines, to the start of the
229236 * buffer, so deleting the FIRST logical line, and thus free up
230237 * an equivalent amount of space at the end.
238+ *
239+ * Note: we might get away with a single memcpy() of the entire
240+ * portion of the buffer, from the SECOND line onward, backwards
241+ * to overwrite the FIRST line, but that would entail copying of
242+ * overlapping memory regions, which is technically described as
243+ * causing undefined behaviour; to avoid any possible problems,
244+ * we identify a block size equal to the space occupied by the
245+ * first line...
231246 */
232- for( caret = console_buffer; mark < endptr; )
233- *caret++ = *mark++;
247+ size_t residual = caret - mark;
248+ size_t block_size = mark - (caret = console_buffer);
249+ while( residual >= block_size )
250+ {
251+ /* ...then copy the residual, in chunks of that size, (so that
252+ * there is never any overlap), until we reduce the residual to
253+ * less than the block size...
254+ */
255+ memcpy( caret, mark, block_size );
256+ residual -= block_size; caret = mark; mark += block_size;
257+ }
258+ if( residual > 0 )
259+ {
260+ /* ...finishing up by copying any lesser sized final residual,
261+ * and leaving the caret at the start of the space so freed.
262+ */
263+ memcpy( caret, mark, residual );
264+ caret += residual;
265+ }
234266 }
235267 }
236268 /* Finally, store the current character into the "device" buffer, and
--- a/src/tarproc.cpp
+++ b/src/tarproc.cpp
@@ -96,7 +96,24 @@ static int create_output_stream( const char *name, int mode )
9696 /* Overwrite prevention was triggered; diagnose.
9797 */
9898 dmh_notify_extraction_failed( name );
99- dmh_notify( DMH_ERROR, "cannot replace existing file\n" );
99+ if( errno == EEXIST )
100+ {
101+ /* The exception was triggered by an already existing file;
102+ * this likely indicates a conflict between two packages.
103+ */
104+ dmh_notify( DMH_ERROR,
105+ "%s: probable package conflict; existing file not overwritten\n",
106+ name
107+ );
108+ }
109+ else
110+ { /* Otherwise, the user isn't allowed to write the extracted
111+ * file, in the location designated for installation.
112+ */
113+ dmh_notify( DMH_ERROR,
114+ "%s: permission denied; cannot store file\n", name
115+ );
116+ }
100117 }
101118 return fd;
102119 }
@@ -146,9 +163,11 @@ int pkgArchiveProcessor::ExtractFile( int fd, const char *pathname, int status )
146163 }
147164 }
148165 }
149- /* Finally, we pass the original status value back to the caller.
166+ /* Finally, we pass either the original status value, or the
167+ * failing file descriptor as an effective status, if no file
168+ * could be extracted, back to the caller.
150169 */
151- return status;
170+ return (fd == -1) ? fd : status;
152171 }
153172
154173 /*******************