MCPcopy Index your code
hub / github.com/coder/coder / escapePostgresURLUserInfo

Function escapePostgresURLUserInfo

cli/server.go:3350–3387  ·  view source on GitHub ↗

If the user provides a postgres URL with a password that contains special characters, the URL will be invalid. We need to escape the password so that the URL parse doesn't fail at the DB connector level.

(v string)

Source from the content-addressed store, hash-verified

3348// characters, the URL will be invalid. We need to escape the password so that
3349// the URL parse doesn't fail at the DB connector level.
3350func escapePostgresURLUserInfo(v string) (string, error) {
3351 _, err := url.Parse(v)
3352 // I wish I could use errors.Is here, but this error is not declared as a
3353 // variable in net/url. :(
3354 if err != nil {
3355 // Warning: The parser may also fail with an "invalid port" error if the password contains special
3356 // characters. It does not detect invalid user information but instead incorrectly reports an invalid port.
3357 //
3358 // See: https://github.com/coder/coder/issues/16319
3359 if strings.Contains(err.Error(), "net/url: invalid userinfo") || reInvalidPortAfterHost.MatchString(err.Error()) {
3360 // If the URL is invalid, we assume it is because the password contains
3361 // special characters that need to be escaped.
3362
3363 // get everything before first @
3364 parts := strings.SplitN(v, "@", 2)
3365 if len(parts) != 2 {
3366 return "", xerrors.Errorf("invalid postgres url with userinfo: %s", v)
3367 }
3368 start := parts[0]
3369 // get password, which is the last item in start when split by :
3370 startParts := strings.Split(start, ":")
3371 password := startParts[len(startParts)-1]
3372 // escape password, and replace the last item in the startParts slice
3373 // with the escaped password.
3374 //
3375 // url.PathEscape is used here because url.QueryEscape
3376 // will not escape spaces correctly.
3377 newPassword := url.PathEscape(password)
3378 startParts[len(startParts)-1] = newPassword
3379 start = strings.Join(startParts, ":")
3380 return start + "@" + parts[1], nil
3381 }
3382
3383 return "", xerrors.Errorf("parse postgres url: %w", err)
3384 }
3385
3386 return v, nil
3387}
3388
3389func signalNotifyContext(ctx context.Context, inv *serpent.Invocation, sig ...os.Signal) (context.Context, context.CancelFunc) {
3390 // On Windows, some of our signal functions lack support.

Callers 2

getAndMigratePostgresDBFunction · 0.85

Calls 4

ParseMethod · 0.65
ContainsMethod · 0.45
ErrorMethod · 0.45
ErrorfMethod · 0.45

Tested by 1