mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-18 03:57:06 +08:00
v0.3.8
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
package forwarder
|
||||
|
||||
import "strings"
|
||||
|
||||
// prepareWriteContentsForClient applies a narrow Windows compatibility shim for
|
||||
// whole-file Write. Some Windows clients write CRLF payloads as CRCRLF on disk,
|
||||
// so we send LF-only content when the target path is clearly a Windows path and
|
||||
// the logical contents already use CRLF. The client's text-mode write then
|
||||
// expands LF back to the intended CRLF on disk.
|
||||
func prepareWriteContentsForClient(path string, contents string) string {
|
||||
if !looksLikeWindowsPath(path) || !strings.Contains(contents, "\r\n") {
|
||||
return contents
|
||||
}
|
||||
return normalizeCRLFToLF(contents)
|
||||
}
|
||||
|
||||
// preparePatchEditWriteContentsForClient sends LF-only transport for PatchEdit.
|
||||
// The client write path may expand LF to the platform newline, so sending CRLF
|
||||
// can become CRCRLF on disk.
|
||||
func preparePatchEditWriteContentsForClient(contents string) string {
|
||||
if !strings.Contains(contents, "\r") {
|
||||
return contents
|
||||
}
|
||||
return normalizeObservedLineEndingsToLF(contents)
|
||||
}
|
||||
|
||||
// reconcilePostWriteObservedContent only corrects one known Windows anomaly:
|
||||
// every line ending in the expected content was duplicated during write-back
|
||||
// verification, which makes the file appear to contain a blank line between
|
||||
// each real line. Some read paths normalize line endings to LF, so the
|
||||
// comparison also checks the normalized representation.
|
||||
func reconcilePostWriteObservedContent(expected string, observed string) (string, bool) {
|
||||
if observed == expected {
|
||||
return observed, false
|
||||
}
|
||||
if observed == systematicallyDoubledLineEndings(expected) {
|
||||
return expected, true
|
||||
}
|
||||
expectedNormalized := normalizeObservedLineEndingsToLF(expected)
|
||||
observedNormalized := normalizeObservedLineEndingsToLF(observed)
|
||||
if observedNormalized == expectedNormalized {
|
||||
return expected, true
|
||||
}
|
||||
if observedNormalized == systematicallyDoubledLineEndings(expectedNormalized) {
|
||||
return expected, true
|
||||
}
|
||||
return observed, false
|
||||
}
|
||||
|
||||
func systematicallyDoubledLineEndings(content string) string {
|
||||
if content == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
builder.Grow(len(content) * 2)
|
||||
for index := 0; index < len(content); {
|
||||
switch {
|
||||
case content[index] == '\r' && index+1 < len(content) && content[index+1] == '\n':
|
||||
builder.WriteString("\r\n\r\n")
|
||||
index += 2
|
||||
case content[index] == '\n':
|
||||
builder.WriteString("\n\n")
|
||||
index++
|
||||
default:
|
||||
builder.WriteByte(content[index])
|
||||
index++
|
||||
}
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func normalizeObservedLineEndingsToLF(content string) string {
|
||||
if content == "" {
|
||||
return ""
|
||||
}
|
||||
normalized := normalizeCRLFToLF(content)
|
||||
return strings.ReplaceAll(normalized, "\r", "\n")
|
||||
}
|
||||
|
||||
func normalizeCRLFToLF(content string) string {
|
||||
if content == "" || !strings.Contains(content, "\r\n") {
|
||||
return content
|
||||
}
|
||||
return strings.ReplaceAll(content, "\r\n", "\n")
|
||||
}
|
||||
|
||||
func looksLikeWindowsPath(path string) bool {
|
||||
trimmed := strings.TrimSpace(path)
|
||||
if len(trimmed) >= 3 && isASCIILetter(trimmed[0]) && trimmed[1] == ':' {
|
||||
return trimmed[2] == '\\' || trimmed[2] == '/'
|
||||
}
|
||||
return strings.HasPrefix(trimmed, `\\`)
|
||||
}
|
||||
|
||||
func isASCIILetter(value byte) bool {
|
||||
return (value >= 'a' && value <= 'z') || (value >= 'A' && value <= 'Z')
|
||||
}
|
||||
Reference in New Issue
Block a user