{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/3358","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/3358/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/3358/comments","events_url":"https://api.github.com/repos/golang/go/issues/3358/events","html_url":"https://github.com/golang/go/issues/3358","id":51280467,"number":3358,"title":"os: some functions fail if full paths are long (more than about 250 chars) on windows","user":{"login":"alexbrainman","id":9796621,"avatar_url":"https://avatars.githubusercontent.com/u/9796621?v=3","gravatar_id":"","url":"https://api.github.com/users/alexbrainman","html_url":"https://github.com/alexbrainman","followers_url":"https://api.github.com/users/alexbrainman/followers","following_url":"https://api.github.com/users/alexbrainman/following{/other_user}","gists_url":"https://api.github.com/users/alexbrainman/gists{/gist_id}","starred_url":"https://api.github.com/users/alexbrainman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexbrainman/subscriptions","organizations_url":"https://api.github.com/users/alexbrainman/orgs","repos_url":"https://api.github.com/users/alexbrainman/repos","events_url":"https://api.github.com/users/alexbrainman/events{/privacy}","received_events_url":"https://api.github.com/users/alexbrainman/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/golang/go/labels/OS-Windows","name":"OS-Windows","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/6","html_url":"https://github.com/golang/go/milestones/Unplanned","labels_url":"https://api.github.com/repos/golang/go/milestones/6/labels","id":1055141,"number":6,"title":"Unplanned","description":"No plan to fix in any specific release.\r\n","creator":{"login":"rsc","id":104030,"avatar_url":"https://avatars.githubusercontent.com/u/104030?v=3","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":1305,"closed_issues":334,"state":"open","created_at":"2015-04-06T20:47:19Z","updated_at":"2016-04-10T03:10:05Z","due_on":"2099-12-31T05:00:00Z","closed_at":null},"comments":25,"created_at":"2012-03-20T05:47:54Z","updated_at":"2016-04-10T12:24:21Z","closed_at":null,"body":"<pre>This program creates directory, but fails to create file inside (CAREFUL IF CHANGING\nTHIS PROGRAM - YOU MIGHT END UP WITH FILES/DIRECTORIES YOU WILL NOT BE ABLE TO DELETE\nWITH STANDARD SHELL TOOLS):\n\npackage main\n\nimport (\n\t&quot;fmt&quot;\n\t&quot;log&quot;\n\t&quot;os&quot;\n\t&quot;strings&quot;\n)\n\nfunc main() {\n//\troot := `\\\\?\\c:\\`\n\troot := `c:\\`\n\tdir := root + strings.Repeat(&quot;d&quot;, 200)\n\tfile := dir + `\\` + strings.Repeat(&quot;f&quot;, 200)\n\terr := os.Mkdir(dir, 0777)\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Mkdir(%s): %v&quot;, dir, err)\n\t}\n\tf, err := os.Create(file)\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Create(%s): %v&quot;, file, err)\n\t}\n\t_, err = fmt.Fprintf(f, &quot;Hello world&quot;)\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Fprintf(%s): %v&quot;, file, err)\n\t}\n\terr = f.Close()\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Close(%s): %v&quot;, file, err)\n\t}\n\terr = os.Remove(file)\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Remove(%s): %v&quot;, file, err)\n\t}\n\terr = os.Remove(dir)\n\tif err != nil {\n\t\tlog.Fatalf(&quot;Remove(%s): %v&quot;, dir, err)\n\t}\n}\n\nThis can be handled properly if we use \\\\?\\ path prefix (uncomment line in the code).\nBut \\\\?\\ prefixed paths needs to be &quot;normalized&quot;: they have to be absolute, no\n. or .. allowed, / is not allowed, UNC paths needs to be handled properly. See\n<a href=\"http://goo.gl/th2fJ\">http://goo.gl/th2fJ</a> for details, especially &quot;Maximum Path Length Limitation&quot;\nsection.\n\nThis issue has come up on our own builder: <a href=\"http://goo.gl/FbblU\">http://goo.gl/FbblU</a>. Perhaps our own paths do\nnot need to be that long. I did not look into that yet.\n\nAlex</pre>"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/207978113","html_url":"https://github.com/golang/go/issues/3358#issuecomment-207978113","issue_url":"https://api.github.com/repos/golang/go/issues/3358","id":207978113,"user":{"login":"xStrom","id":754881,"avatar_url":"https://avatars.githubusercontent.com/u/754881?v=3","gravatar_id":"","url":"https://api.github.com/users/xStrom","html_url":"https://github.com/xStrom","followers_url":"https://api.github.com/users/xStrom/followers","following_url":"https://api.github.com/users/xStrom/following{/other_user}","gists_url":"https://api.github.com/users/xStrom/gists{/gist_id}","starred_url":"https://api.github.com/users/xStrom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xStrom/subscriptions","organizations_url":"https://api.github.com/users/xStrom/orgs","repos_url":"https://api.github.com/users/xStrom/repos","events_url":"https://api.github.com/users/xStrom/events{/privacy}","received_events_url":"https://api.github.com/users/xStrom/received_events","type":"User","site_admin":false},"created_at":"2016-04-10T12:24:21Z","updated_at":"2016-04-10T12:24:21Z","body":"Is anyone currently working on a solution for this? I am willing to supply a fix myself, but I was asked to consolidate planning in this thread.\r\n\r\nAs evidenced by the slew of issues referencing this one, this bug is affecting people all the time. With the explosive growth of node's popularity, we can only expect the frequency of people running into this bug to grow similarly. Indeed I ran into this while using the govendor tool on a rather simple project that contains gulp: `C:\\Gopath\\src\\bitbucket.org\\xStrom\\lopya\\node_modules\\gulp\\node_modules\\gulp-util\\node_modules\\dateformat\\node_modules\\meow\\node_modules\\normalize-package-data\\node_modules\\validate-npm-package-license\\node_modules\\spdx-correct\\node_modules\\spdx-license-ids\\LICENSE`.\r\n\r\nAs mentioned in this thread, it is currently possible to supply \"\\\\\\\\?\\\\\" prepended paths to some of the `os` package functions to solve the issue. This however goes directly against the claim made in the `os` package documentation: [\"a platform-independent interface to operating system functionality\"](https://golang.org/pkg/os/). There's nothing platform-independent about an if-windows-then-prepend block before every function call.\r\n\r\nThen there's also the problem that Windows API does some magic handling of paths shorter than MAX_PATH. Replacing \"/\" with \"\\\\\" etc. So if we just start prepending \"\\\\\\\\?\\\\\" then people's existing code will start breaking, if they're using *C:/foo/bar.txt* or something similar as input.\r\n\r\nI think a reasonable solution would be to do a length check on the path name before syscalling. If the name fits MAX_PATH, then use it as is, and enjoy the extra magic. If the name exceeds MAX_PATH and doesn't already start with \"\\\\\\\\?\\\\\", then we can only benefit from prepending \"\\\\\\\\?\\\\\". This solution is backwards compatible with magic-needing paths (e.g. *C:/foo/bar.txt*) that are already being used in the wild, and is also backwards compatible with code that already has their own if-windows-then-prepend block. Yes no magic would be applied to long paths, but those magic-needing long paths don't work currently either."}}