notepad-plus-plus / notepad-plus-plus

Notepad++ official repository
https://notepad-plus-plus.org/
Other
23.02k stars 4.61k forks source link

Notepad++ deletes and rewrites files on "save", this deleting all the file attributes and metadat #4818

Open smallscript opened 6 years ago

smallscript commented 6 years ago

Notepad++ deletes and rewrites files on "save", thus deleting all the file attributes and metadata.

I've investigated, fixed and test-case verified the issue. It is a two-party at fault problem.

  1. NPP is not using "wb+" (so not indicating it is a update to any existing file).

  2. Microsoft has a CRT error in the lib for "generic_fopen" (Unicode and ANSI); which I filed on VisualStudio CRT with Microsoft.

    Sad to see such a bad (code design) bug in Microsoft's CRT core; I worked in Microsoft DevDiv as an Architect for many years.

  3. Required changing PowerEditor/src/ScitillaComponent/Buffer.cpp lines 881 and 1070 to use "wb+" rather than "wb".

  4. Required more "munging" because I had to use "ab+" then make it look like it had been invoked with "wb+". Those changes were in PowerEditor/src/Utf8_16.cpp lines 20 (to include <io.h> and 278. LINE 20: #include <io.h> // dsim: Patch bad fopen + mode LINE 278:

    #ifdef _MSC_VER 
    // dsim: Horrible Microsoft CRT bug with "+"
    auto const nType = _type ? _tcslen(_type) : 0;
    if (nType && _type[nType - 1] == '+' && _type[0] == 'w') {
    TCHAR* zType = reinterpret_cast<TCHAR*>(alloca((nType + 1) * sizeof(TCHAR)));
    memcpy(zType, _type, nType * sizeof(TCHAR)); zType[nType] = 0; zType[0] = 'a';
    m_pFile = ::generic_fopen(_name, zType);
    if (m_pFile != nullptr) {
      fseek(m_pFile, 0, SEEK_SET);
      _chsize_s(fileno(m_pFile), 0); //ftruncate(m_pFile, 0);
    }
    }
    else {
    m_pFile = ::generic_fopen(_name, _type);
    }
    #else
    m_pFile = ::generic_fopen(_name, _type);
    #endif
barbudor commented 3 years ago

On Windows this also break any hardlink making the file "standalone" if it was previously a hardlink to another file.