/ Check-in [4a438556]
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 | SQL archive
Timelines: family | ancestors | descendants | both | follow-symlinks
Files: files | file ages | folders
SHA1:4a4385564dd3887a7953820b60c99d6ce289f96a
User & Date: dan 2016-01-26 13:56:42
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: 4003db4a user: dan tags: trunk
13:56
Ensure that unixFullpathname() always nul-terminates its output buffer, even when returning an error. Closed-Leaf check-in: 4a438556 user: dan tags: follow-symlinks
00:12
Remove an unused variable. check-in: 1c2656c1 user: drh tags: follow-symlinks
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

5951
5952
5953
5954
5955
5956
5957




5958

5959
5960
5961
5962
5963
5964
5965
....
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
  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
................................................................................
        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);







>
>
>
>
|
>







 







>
|
|
|
|
|
|
|
|
|
>








|
|







5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
....
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
  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
................................................................................
        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
192
  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}

finish_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

  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}

finish_test