Fix PR review feedback
- Preserve SSRF protection by wrapping the existing transport instead of replacing it with a bare http.Transport - Strip DSN from url.Parse error to avoid leaking credentials - Gate CommonThirdPartyCombobox on search length to prevent showing stale results when input is shortened - Handle multi-value and uppercase sizes attributes in parseSizeAttr for correct icon-size ranking - Match rel tokens containing "icon" (e.g. "shortcut icon") instead of requiring an exact match - Limit HTML response body to 10 MiB before parsing - Reject sslmode=prefer explicitly in both import tools Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -98,7 +98,7 @@ export function CreateVendorDialog({
|
||||
<Dialog ref={dialogRef} trigger={children} title={__("Add a vendor")}>
|
||||
<DialogContent className="p-6">
|
||||
<Combobox onSearch={handleSearch} placeholder={__("Type vendor's name")}>
|
||||
{queryRef && (
|
||||
{searchQuery.trim().length >= 2 && queryRef && (
|
||||
<Suspense>
|
||||
<CommonThirdPartyCombobox
|
||||
queryRef={queryRef}
|
||||
|
||||
@@ -454,7 +454,7 @@ func parseCategory(tp thirdPartyData) coredata.VendorCategory {
|
||||
func newPgClientFromDSN(dsn string) (*pg.Client, error) {
|
||||
u, err := url.Parse(dsn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse DSN: %w", err)
|
||||
return nil, fmt.Errorf("cannot parse DSN (check URL format)")
|
||||
}
|
||||
|
||||
var opts []pg.Option
|
||||
@@ -462,10 +462,12 @@ func newPgClientFromDSN(dsn string) (*pg.Client, error) {
|
||||
switch u.Query().Get("sslmode") {
|
||||
case "", "disable":
|
||||
// plain connection, no TLS
|
||||
case "require", "prefer":
|
||||
case "require":
|
||||
opts = append(opts, pg.WithUnsecureTLS())
|
||||
case "prefer":
|
||||
return nil, fmt.Errorf("unsupported sslmode %q (prefer fallback semantics are not supported)", u.Query().Get("sslmode"))
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported sslmode %q (only disable, require, prefer are supported)", u.Query().Get("sslmode"))
|
||||
return nil, fmt.Errorf("unsupported sslmode %q", u.Query().Get("sslmode"))
|
||||
}
|
||||
|
||||
if u.Host != "" {
|
||||
|
||||
@@ -82,10 +82,12 @@ func newPgClientFromDSN(dsn string) (*pg.Client, error) {
|
||||
switch u.Query().Get("sslmode") {
|
||||
case "", "disable":
|
||||
// plain connection, no TLS
|
||||
case "require", "prefer":
|
||||
case "require":
|
||||
opts = append(opts, pg.WithUnsecureTLS())
|
||||
case "prefer":
|
||||
return nil, fmt.Errorf("unsupported sslmode %q (prefer fallback semantics are not supported)", u.Query().Get("sslmode"))
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported sslmode %q (only disable, require, prefer are supported)", u.Query().Get("sslmode"))
|
||||
return nil, fmt.Errorf("unsupported sslmode %q", u.Query().Get("sslmode"))
|
||||
}
|
||||
|
||||
if u.Host != "" {
|
||||
|
||||
@@ -45,7 +45,7 @@ func FindLogoURL(info *PageInfo) (string, error) {
|
||||
}
|
||||
|
||||
switch {
|
||||
case rel == "icon" && attrVal(n, "type") == "image/svg+xml":
|
||||
case strings.Contains(rel, "icon") && !strings.Contains(rel, "apple-touch-icon") && attrVal(n, "type") == "image/svg+xml":
|
||||
svgIcon = href
|
||||
case strings.Contains(rel, "apple-touch-icon"):
|
||||
size := parseSizeAttr(attrVal(n, "sizes"))
|
||||
@@ -53,7 +53,7 @@ func FindLogoURL(info *PageInfo) (string, error) {
|
||||
appleTouchIcon = href
|
||||
appleTouchSize = size
|
||||
}
|
||||
case rel == "icon":
|
||||
case strings.Contains(rel, "icon") && !strings.Contains(rel, "apple-touch-icon"):
|
||||
size := parseSizeAttr(attrVal(n, "sizes"))
|
||||
if largestIcon == "" || size > largestSize {
|
||||
largestIcon = href
|
||||
@@ -87,21 +87,29 @@ func FindLogoURL(info *PageInfo) (string, error) {
|
||||
}
|
||||
|
||||
func parseSizeAttr(sizes string) int {
|
||||
if sizes == "" || strings.ToLower(sizes) == "any" {
|
||||
if sizes == "" || strings.EqualFold(sizes, "any") {
|
||||
return 0
|
||||
}
|
||||
|
||||
parts := strings.SplitN(sizes, "x", 2)
|
||||
if len(parts) == 0 {
|
||||
return 0
|
||||
best := 0
|
||||
for _, token := range strings.Fields(sizes) {
|
||||
token = strings.ToLower(token)
|
||||
parts := strings.SplitN(token, "x", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
w, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if w > best {
|
||||
best = w
|
||||
}
|
||||
}
|
||||
|
||||
w, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return w
|
||||
return best
|
||||
}
|
||||
|
||||
func ExtensionForMIME(contentType string) string {
|
||||
|
||||
@@ -50,7 +50,8 @@ func Parse(ctx context.Context, client *http.Client, websiteURL string) (*PageIn
|
||||
return nil, fmt.Errorf("cannot fetch page: status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return ParseHTML(parsed, resp.Body)
|
||||
const maxHTMLSize = 10 << 20 // 10 MiB
|
||||
return ParseHTML(parsed, io.LimitReader(resp.Body, maxHTMLSize))
|
||||
}
|
||||
|
||||
func ParseHTML(baseURL *url.URL, r io.Reader) (*PageInfo, error) {
|
||||
|
||||
Reference in New Issue
Block a user