(ctx context.Context, fullMethod string, msg any)
| 98 | ) |
| 99 | |
| 100 | func validateMessage(ctx context.Context, fullMethod string, msg any) error { |
| 101 | var paths []string |
| 102 | switch v := msg.(type) { |
| 103 | case interface { |
| 104 | GetFieldMask() *fieldmaskpb.FieldMask |
| 105 | }: |
| 106 | paths = v.GetFieldMask().GetPaths() |
| 107 | } |
| 108 | if len(paths) > 0 { |
| 109 | region := trace.StartRegion(ctx, "validate field mask") |
| 110 | |
| 111 | if forbiddenPaths := forbiddenPaths(paths, allowedFieldMaskPaths[fullMethod]); len(forbiddenPaths) > 0 { |
| 112 | region.End() |
| 113 | return errForbiddenFieldMaskPaths.WithAttributes("forbidden_paths", forbiddenPaths) |
| 114 | } |
| 115 | |
| 116 | isZeroPaths, ok := isZeroFieldMaskPaths[fullMethod] |
| 117 | if ok && len(isZeroPaths) > 0 { |
| 118 | var isZero func(string) bool |
| 119 | outer: |
| 120 | for _, p := range paths { |
| 121 | prefix := p + "." |
| 122 | i := sort.Search(len(isZeroPaths), func(i int) bool { |
| 123 | return strings.HasPrefix(isZeroPaths[i], prefix) |
| 124 | }) |
| 125 | if i == len(isZeroPaths) || !strings.HasPrefix(isZeroPaths[i], prefix) { |
| 126 | continue |
| 127 | } |
| 128 | tail := isZeroPaths[i+1:] |
| 129 | for _, sp := range isZeroPaths[i : i+1+sort.Search(len(tail), func(j int) bool { |
| 130 | return !strings.HasPrefix(tail[j], prefix) |
| 131 | })] { |
| 132 | if isZero == nil { |
| 133 | if v, ok := msg.(interface { |
| 134 | FieldIsZero(string) bool |
| 135 | }); ok { |
| 136 | isZero = v.FieldIsZero |
| 137 | } else { |
| 138 | break outer |
| 139 | } |
| 140 | } |
| 141 | if !isZero(sp) { |
| 142 | region.End() |
| 143 | return errNonZeroPath.WithAttributes("path", sp) |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | region.End() |
| 149 | } |
| 150 | |
| 151 | switch v := msg.(type) { |
| 152 | case interface { |
| 153 | ValidateContext(context.Context) error |
| 154 | }: |
| 155 | defer trace.StartRegion(ctx, "validate with context").End() |
| 156 | if err := v.ValidateContext(ctx); err != nil { |
| 157 | return convertError(err) |
no test coverage detected