[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [MiNT] ext2 bug Was Re: another getcwd fix (includes previous patch)
On Thu, 2008-01-10 at 17:55 +0100, Andreas Schwab wrote:
> Alan Hourihane <alanh@fairlite.demon.co.uk> writes:
>
> > @@ -64,12 +74,23 @@
> > path[0] = '\\';
> > path[1] = '\0';
> > }
> > - _dos2unx(path, buf, size);
> > + r = _dos2unx(path, buf, size);
> > }
> > - else
> > + else {
> > /* convert DOS filename to unix */
> > - _dos2unx(_path, buf, size);
> > + r = _dos2unx(_path, buf, size);
> > + }
> > +
> > + /* dos2unx failed, probably ENAMETOOLONG, so abort now */
> > + if (r == -1) {
> > + free(_path);
> > + if (buf_malloced)
> > + free(buf);
> > + return NULL;
>
> You need to preserve errno around the calls to free.
Thanks for your review too Andreas. It's late in the working day....
Attached.
Alan.
Index: mintlib/getcwd.c
===================================================================
RCS file: /mint/mintlib/mintlib/getcwd.c,v
retrieving revision 1.6
diff -u -r1.6 getcwd.c
--- mintlib/getcwd.c 8 Oct 2003 15:23:14 -0000 1.6
+++ mintlib/getcwd.c 10 Jan 2008 17:10:23 -0000
@@ -24,20 +24,29 @@
char *
__getcwd (char *buf, size_t size)
{
- const int len = (size > 0 ? size : PATH_MAX) + 16;
- char _path[len]; /* XXX non ANSI */
- char *path;
+ int len;
+ char *path, *_path;
char drv;
int buf_malloced = 0;
int r;
+ len = (size > 0 ? size : PATH_MAX) + 16;
+ _path = malloc(len);
+ if (!_path) {
+ __set_errno(ENOMEM);
+ return NULL;
+ }
+
if (!buf) {
if (size == 0)
size = PATH_MAX;
buf = malloc (size);
- if (!buf)
+ if (!buf) {
+ free(_path);
+ __set_errno(ENOMEM);
return NULL;
+ }
buf_malloced = 1;
}
@@ -50,6 +59,7 @@
r = (int) Dgetcwd(path, 0, len - 2);
if (r != 0 && r != -ENOSYS) {
+ free(_path);
if (buf_malloced)
free(buf);
__set_errno (-r);
@@ -64,12 +74,25 @@
path[0] = '\\';
path[1] = '\0';
}
- _dos2unx(path, buf, size);
+ r = _dos2unx(path, buf, size);
}
- else
+ else {
/* convert DOS filename to unix */
- _dos2unx(_path, buf, size);
+ r = _dos2unx(_path, buf, size);
+ }
+
+ /* dos2unx failed, probably ENAMETOOLONG, so abort now */
+ if (r == -1) {
+ const int saved_errno = errno;
+ free(_path);
+ if (buf_malloced)
+ free(buf);
+ __set_errno(saved_errno);
+ return NULL;
+ }
+ free(_path);
+
if (buf_malloced) {
size_t len = strlen (buf) + 1;
void *newptr;
Index: mintlib/unx2dos.c
===================================================================
RCS file: /mint/mintlib/mintlib/unx2dos.c,v
retrieving revision 1.5
diff -u -r1.5 unx2dos.c
--- mintlib/unx2dos.c 8 Oct 2003 15:23:14 -0000 1.5
+++ mintlib/unx2dos.c 10 Jan 2008 17:10:23 -0000
@@ -1,5 +1,6 @@
#include <ctype.h>
+#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
@@ -11,11 +12,15 @@
/*
* returns 0 for ordinary files, 1 for special files (like /dev/tty)
+ *
+ * or returns -1 on error, such as ENAMETOOLONG
*/
int
_unx2dos(const char *unx, char *dos, size_t len)
{
+ register int unx_length = strlen(unx);
+ register int count = 0;
const char *u;
char *d, c;
@@ -76,6 +81,7 @@
}
while( (c = *u++) != 0 ) {
+ count++;
if (c == '/')
c = '\\';
#if 0
@@ -91,8 +97,14 @@
#endif
*d++ = c;
len--;
- if (len == 0)
+ if (len == 0) {
+ if (count < unx_length) {
+ __set_errno(ENAMETOOLONG);
+ *d = 0;
+ return -1;
+ }
break;
+ }
}
*d = 0;
return 0;
@@ -101,6 +113,8 @@
int
_dos2unx(const char *dos, char *unx, size_t len)
{
+ register int dos_length = strlen(dos);
+ register int count = 0;
register char c;
len--; /* for terminating NUL */
@@ -133,14 +147,21 @@
/* convert slashes
*/
while ( (c = *dos++) != 0) {
+ count++;
if (c == '\\')
c = '/';
else if (__mint < 7)
c = tolower(c);
*unx++ = c;
len--;
- if (len == 0)
+ if (len == 0) {
+ if (count < dos_length) {
+ __set_errno(ENAMETOOLONG);
+ *unx = 0;
+ return -1;
+ }
break;
+ }
}
*unx = 0;
return 0;