SQLite

Check-in [4a4385564d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Ensure that unixFullpathname() always nul-terminates its output buffer, even when returning an error.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | follow-symlinks
Files: files | file ages | folders
SHA1: 4a4385564dd3887a7953820b60c99d6ce289f96a
User & Date: dan 2016-01-26 13:56:42.494
Context
2016-01-26
14:48
Fix issues on unix with opening database files via symlinks that are not in the current working directory. And with nested symlinks. (check-in: 4003db4a49 user: dan tags: trunk)
13:56
Ensure that unixFullpathname() always nul-terminates its output buffer, even when returning an error. (Closed-Leaf check-in: 4a4385564d user: dan tags: follow-symlinks)
00:12
Remove an unused variable. (check-in: 1c2656c1d3 user: drh tags: follow-symlinks)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
5951
5952
5953
5954
5955
5956
5957
5958





5959
5960
5961
5962
5963
5964
5965
  if( zPath[0]!='/' ){
    if( osGetcwd(zOut, nOut-2)==0 ){
      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
    }
    iOff = sqlite3Strlen30(zOut);
    zOut[iOff++] = '/';
  }
  if( (iOff+nPath+1)>nOut ) return SQLITE_CANTOPEN_BKPT;





  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
  return SQLITE_OK;
}

/*
** Turn a relative pathname into a full pathname. The relative path
** is stored as a nul-terminated string in the buffer pointed to by







|
>
>
>
>
>







5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
  if( zPath[0]!='/' ){
    if( osGetcwd(zOut, nOut-2)==0 ){
      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
    }
    iOff = sqlite3Strlen30(zOut);
    zOut[iOff++] = '/';
  }
  if( (iOff+nPath+1)>nOut ){
    /* SQLite assumes that xFullPathname() nul-terminates the output buffer
    ** even if it returns an error.  */
    zOut[iOff] = '\0';
    return SQLITE_CANTOPEN_BKPT;
  }
  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
  return SQLITE_OK;
}

/*
** Turn a relative pathname into a full pathname. The relative path
** is stored as a nul-terminated string in the buffer pointed to by
6016
6017
6018
6019
6020
6021
6022

6023
6024
6025
6026
6027
6028
6029
6030
6031

6032
6033
6034
6035
6036
6037
6038
6039

6040
6041
6042
6043
6044
6045
6046
6047
6048
        rc = SQLITE_CANTOPEN_BKPT;
      }

      if( rc==SQLITE_OK ){
        nByte = osReadlink(zIn, zDel, nOut-1);
        if( nByte<0 ){
          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);

        }else if( zDel[0]!='/' ){
          int n;
          for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
          if( nByte+n+1>nOut ){
            rc = SQLITE_CANTOPEN_BKPT;
          }else{
            memmove(&zDel[n], zDel, nByte+1);
            memcpy(zDel, zIn, n);
            nByte += n;

          }
          zDel[nByte] = '\0';
        }
      }

      zIn = zDel;
    }


    if( rc==SQLITE_OK ){
      assert( zIn!=zOut || zIn[0]=='/' );
      rc = mkFullPathname(zIn, zOut, nOut);
    }
    if( bLink==0 ) break;
    zIn = zOut;
  }while( rc==SQLITE_OK );

  sqlite3_free(zDel);







>
|
|
|
|
|
|
|
|
|
>








>
|
<







6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048

6049
6050
6051
6052
6053
6054
6055
        rc = SQLITE_CANTOPEN_BKPT;
      }

      if( rc==SQLITE_OK ){
        nByte = osReadlink(zIn, zDel, nOut-1);
        if( nByte<0 ){
          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
        }else{
          if( zDel[0]!='/' ){
            int n;
            for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
            if( nByte+n+1>nOut ){
              rc = SQLITE_CANTOPEN_BKPT;
            }else{
              memmove(&zDel[n], zDel, nByte+1);
              memcpy(zDel, zIn, n);
              nByte += n;
            }
          }
          zDel[nByte] = '\0';
        }
      }

      zIn = zDel;
    }

    assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
    if( rc==SQLITE_OK && zIn!=zOut ){

      rc = mkFullPathname(zIn, zOut, nOut);
    }
    if( bLink==0 ) break;
    zIn = zOut;
  }while( rc==SQLITE_OK );

  sqlite3_free(zDel);
Changes to test/symlink.test.
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
  forcedelete w
  file mkdir w
  file link w/test.db [file join [pwd] x/test.db] 
  set {} {}
} {}
do_test 4.4.1 {
  db close
  breakpoint
  sqlite3 db w/test.db
  db eval { SELECT * FROM t1 }
} {hello world}
do_test 4.4.2 {
  list [file exists x/test.db-wal] [file exists w/test.db-wal]
} {1 0}








<







177
178
179
180
181
182
183

184
185
186
187
188
189
190
  forcedelete w
  file mkdir w
  file link w/test.db [file join [pwd] x/test.db] 
  set {} {}
} {}
do_test 4.4.1 {
  db close

  sqlite3 db w/test.db
  db eval { SELECT * FROM t1 }
} {hello world}
do_test 4.4.2 {
  list [file exists x/test.db-wal] [file exists w/test.db-wal]
} {1 0}