From 24232d72e975ae4b338cfd0906ce63bc3c65546b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:23:44 +0000 Subject: [PATCH 01/10] Bump golang.org/x/net from 0.17.0 to 0.23.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- go.mod | 6 +-- go.sum | 29 ++++++++------- vendor/golang.org/x/net/html/token.go | 12 ++++-- vendor/golang.org/x/sys/windows/aliases.go | 1 - vendor/golang.org/x/sys/windows/empty.s | 1 - .../golang.org/x/sys/windows/env_windows.go | 17 +++++---- vendor/golang.org/x/sys/windows/eventlog.go | 1 - vendor/golang.org/x/sys/windows/mksyscall.go | 1 - vendor/golang.org/x/sys/windows/race.go | 1 - vendor/golang.org/x/sys/windows/race0.go | 1 - vendor/golang.org/x/sys/windows/service.go | 1 - vendor/golang.org/x/sys/windows/str.go | 1 - vendor/golang.org/x/sys/windows/syscall.go | 1 - .../x/sys/windows/syscall_windows.go | 10 +++-- .../golang.org/x/sys/windows/types_windows.go | 28 +++++++++++++- .../x/sys/windows/zsyscall_windows.go | 37 +++++++++++++++++++ vendor/modules.txt | 12 +++--- 17 files changed, 114 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index cedf630..3e4e009 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.17 require ( github.com/mattn/go-sqlite3 v1.14.7 - golang.org/x/net v0.17.0 - golang.org/x/sys v0.13.0 + golang.org/x/net v0.23.0 + golang.org/x/sys v0.18.0 ) -require golang.org/x/text v0.13.0 // indirect +require golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index 9cf1cee..6e7055b 100644 --- a/go.sum +++ b/go.sum @@ -3,16 +3,18 @@ github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -22,22 +24,23 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index de67f93..3c57880 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -910,9 +910,6 @@ func (z *Tokenizer) readTagAttrKey() { return } switch c { - case ' ', '\n', '\r', '\t', '\f', '/': - z.pendingAttr[0].end = z.raw.end - 1 - return case '=': if z.pendingAttr[0].start+1 == z.raw.end { // WHATWG 13.2.5.32, if we see an equals sign before the attribute name @@ -920,7 +917,9 @@ func (z *Tokenizer) readTagAttrKey() { continue } fallthrough - case '>': + case ' ', '\n', '\r', '\t', '\f', '/', '>': + // WHATWG 13.2.5.33 Attribute name state + // We need to reconsume the char in the after attribute name state to support the / character z.raw.end-- z.pendingAttr[0].end = z.raw.end return @@ -939,6 +938,11 @@ func (z *Tokenizer) readTagAttrVal() { if z.err != nil { return } + if c == '/' { + // WHATWG 13.2.5.34 After attribute name state + // U+002F SOLIDUS (/) - Switch to the self-closing start tag state. + return + } if c != '=' { z.raw.end-- return diff --git a/vendor/golang.org/x/sys/windows/aliases.go b/vendor/golang.org/x/sys/windows/aliases.go index a20ebea..ce2d713 100644 --- a/vendor/golang.org/x/sys/windows/aliases.go +++ b/vendor/golang.org/x/sys/windows/aliases.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows && go1.9 -// +build windows,go1.9 package windows diff --git a/vendor/golang.org/x/sys/windows/empty.s b/vendor/golang.org/x/sys/windows/empty.s index fdbbbcd..ba64cac 100644 --- a/vendor/golang.org/x/sys/windows/empty.s +++ b/vendor/golang.org/x/sys/windows/empty.s @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build !go1.12 -// +build !go1.12 // This file is here to allow bodyless functions with go:linkname for Go 1.11 // and earlier (see https://golang.org/issue/23311). diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index b8ad192..d4577a4 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := unsafe.Pointer(block) - for { - entry := UTF16PtrToString((*uint16)(blockp)) - if len(entry) == 0 { - break + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) } - env = append(env, entry) - blockp = unsafe.Add(blockp, 2*(len(entry)+1)) + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go index 2cd6064..6c36695 100644 --- a/vendor/golang.org/x/sys/windows/eventlog.go +++ b/vendor/golang.org/x/sys/windows/eventlog.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows -// +build windows package windows diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go index 8563f79..dbcdb09 100644 --- a/vendor/golang.org/x/sys/windows/mksyscall.go +++ b/vendor/golang.org/x/sys/windows/mksyscall.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build generate -// +build generate package windows diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go index 9196b08..0f1bdc3 100644 --- a/vendor/golang.org/x/sys/windows/race.go +++ b/vendor/golang.org/x/sys/windows/race.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows && race -// +build windows,race package windows diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go index 7bae481..0c78da7 100644 --- a/vendor/golang.org/x/sys/windows/race0.go +++ b/vendor/golang.org/x/sys/windows/race0.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows && !race -// +build windows,!race package windows diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go index c44a1b9..a9dc630 100644 --- a/vendor/golang.org/x/sys/windows/service.go +++ b/vendor/golang.org/x/sys/windows/service.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows -// +build windows package windows diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go index 4fc0143..6a4f9ce 100644 --- a/vendor/golang.org/x/sys/windows/str.go +++ b/vendor/golang.org/x/sys/windows/str.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows -// +build windows package windows diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index 8732cdb..e85ed6b 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build windows -// +build windows // Package windows contains an interface to the low-level operating system // primitives. OS details vary depending on the underlying system, and diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 35cfc57..6395a03 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string { for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - - return string(utf16.Decode(unsafe.Slice(p, n))) + return UTF16ToString(unsafe.Slice(p, n)) } func Getpagesize() int { return 4096 } @@ -155,6 +154,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW //sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW //sys SetDefaultDllDirectories(directoryFlags uint32) (err error) +//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory +//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory //sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW //sys GetVersion() (ver uint32, err error) //sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW @@ -192,6 +193,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] @@ -233,6 +235,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock //sys getTickCount64() (ms uint64) = kernel32.GetTickCount64 +//sys GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) //sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) //sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW //sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW @@ -969,7 +972,8 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { if n > 0 { sl += int32(n) + 1 } - if sa.raw.Path[0] == '@' { + if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) { + // Check sl > 3 so we don't change unnamed socket behavior. sa.raw.Path[0] = 0 // Don't count trailing NUL for abstract address. sl-- diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index b88dc7c..359780f 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1094,7 +1094,33 @@ const ( SOMAXCONN = 0x7fffffff - TCP_NODELAY = 1 + TCP_NODELAY = 1 + TCP_EXPEDITED_1122 = 2 + TCP_KEEPALIVE = 3 + TCP_MAXSEG = 4 + TCP_MAXRT = 5 + TCP_STDURG = 6 + TCP_NOURG = 7 + TCP_ATMARK = 8 + TCP_NOSYNRETRIES = 9 + TCP_TIMESTAMPS = 10 + TCP_OFFLOAD_PREFERENCE = 11 + TCP_CONGESTION_ALGORITHM = 12 + TCP_DELAY_FIN_ACK = 13 + TCP_MAXRTMS = 14 + TCP_FASTOPEN = 15 + TCP_KEEPCNT = 16 + TCP_KEEPIDLE = TCP_KEEPALIVE + TCP_KEEPINTVL = 17 + TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18 + TCP_ICMP_ERROR_INFO = 19 + + UDP_NOCHECKSUM = 1 + UDP_SEND_MSG_SIZE = 2 + UDP_RECV_MAX_COALESCED_SIZE = 3 + UDP_CHECKSUM_COVERAGE = 20 + + UDP_COALESCED_INFO = 3 SHUT_RD = 0 SHUT_WR = 1 diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 8b1688d..e8791c8 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -184,6 +184,7 @@ var ( procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") procCancelIo = modkernel32.NewProc("CancelIo") procCancelIoEx = modkernel32.NewProc("CancelIoEx") @@ -253,6 +254,7 @@ var ( procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") + procGetFileTime = modkernel32.NewProc("GetFileTime") procGetFileType = modkernel32.NewProc("GetFileType") procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") @@ -329,6 +331,7 @@ var ( procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") procReleaseMutex = modkernel32.NewProc("ReleaseMutex") procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") + procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory") procResetEvent = modkernel32.NewProc("ResetEvent") procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole") procResumeThread = modkernel32.NewProc("ResumeThread") @@ -339,6 +342,7 @@ var ( procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") procSetErrorMode = modkernel32.NewProc("SetErrorMode") procSetEvent = modkernel32.NewProc("SetEvent") @@ -1604,6 +1608,15 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { return } +func AddDllDirectory(path *uint16) (cookie uintptr, err error) { + r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + cookie = uintptr(r0) + if cookie == 0 { + err = errnoErr(e1) + } + return +} + func AssignProcessToJobObject(job Handle, process Handle) (err error) { r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0) if r1 == 0 { @@ -2185,6 +2198,14 @@ func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, return } +func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procGetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetFileType(filehandle Handle) (n uint32, err error) { r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) n = uint32(r0) @@ -2870,6 +2891,14 @@ func RemoveDirectory(path *uint16) (err error) { return } +func RemoveDllDirectory(cookie uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func ResetEvent(event Handle) (err error) { r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) if r1 == 0 { @@ -2960,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) { return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) if r1 == 0 { diff --git a/vendor/modules.txt b/vendor/modules.txt index 5d26d2b..5144e2f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,16 +1,16 @@ # github.com/mattn/go-sqlite3 v1.14.7 ## explicit; go 1.12 github.com/mattn/go-sqlite3 -# golang.org/x/net v0.17.0 -## explicit; go 1.17 +# golang.org/x/net v0.23.0 +## explicit; go 1.18 golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset -# golang.org/x/sys v0.13.0 -## explicit; go 1.17 +# golang.org/x/sys v0.18.0 +## explicit; go 1.18 golang.org/x/sys/windows -# golang.org/x/text v0.13.0 -## explicit; go 1.17 +# golang.org/x/text v0.14.0 +## explicit; go 1.18 golang.org/x/text/encoding golang.org/x/text/encoding/charmap golang.org/x/text/encoding/htmlindex From daffd721ebbc62938397869686990b2a7978f254 Mon Sep 17 00:00:00 2001 From: Jason Rogena Date: Sat, 11 May 2024 12:12:41 +0100 Subject: [PATCH 02/10] Allow overriding the GOARCH in the makefile To allow for building yarr for other architectures, make the GOARCH env var overridable in the makefile. Signed-off-by: Jason Rogena --- makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index f8d3609..57e4cbf 100644 --- a/makefile +++ b/makefile @@ -6,25 +6,27 @@ CGO_ENABLED=1 GO_LDFLAGS = -s -w GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)' +export GOARCH ?= amd64 + build_default: mkdir -p _output go build -tags "sqlite_foreign_keys" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr build_macos: mkdir -p _output/macos - GOOS=darwin GOARCH=amd64 go build -tags "sqlite_foreign_keys macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr + GOOS=darwin go build -tags "sqlite_foreign_keys macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr cp src/platform/icon.png _output/macos/icon.png go run ./cmd/package_macos -outdir _output/macos -version "$(VERSION)" build_linux: mkdir -p _output/linux - GOOS=linux GOARCH=amd64 go build -tags "sqlite_foreign_keys linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr + GOOS=linux go build -tags "sqlite_foreign_keys linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr build_windows: mkdir -p _output/windows go run ./cmd/generate_versioninfo -version "$(VERSION)" -outfile src/platform/versioninfo.rc windres -i src/platform/versioninfo.rc -O coff -o src/platform/versioninfo.syso - GOOS=windows GOARCH=amd64 go build -tags "sqlite_foreign_keys windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr + GOOS=windows go build -tags "sqlite_foreign_keys windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr serve: go run -tags "sqlite_foreign_keys" ./cmd/yarr -db local.db From b13cd85f0bf2c77a9e78dff6792a99b9f27d063c Mon Sep 17 00:00:00 2001 From: nkanaev Date: Tue, 14 May 2024 13:22:14 +0100 Subject: [PATCH 03/10] update makefile --- makefile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/makefile b/makefile index 57e4cbf..e0cd718 100644 --- a/makefile +++ b/makefile @@ -1,12 +1,10 @@ VERSION=2.4 GITHASH=$(shell git rev-parse --short=8 HEAD) -CGO_ENABLED=1 +GO_LDFLAGS = -s -w -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)' -GO_LDFLAGS = -s -w -GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)' - -export GOARCH ?= amd64 +export GOARCH ?= amd64 +export CGO_ENABLED = 1 build_default: mkdir -p _output From b9b3d2350c9e12e143c0f40c2efeece4449af061 Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Tue, 11 Jun 2024 13:26:22 +0200 Subject: [PATCH 04/10] atom: Stop unescaping special HTML characters The HTML data in Atom is escaped because the data needs to put as a string to an XML file. If we are accessing it by reading the string value, then it is already unescaped, as opposed to getting the raw XML data. XHTML data don't need to be unescaped either since the elements are already encoded as is in tree. :) Closes #198 --- src/parser/atom.go | 3 +-- src/parser/atom_test.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/parser/atom.go b/src/parser/atom.go index f59bd4a..5bc0c57 100644 --- a/src/parser/atom.go +++ b/src/parser/atom.go @@ -3,7 +3,6 @@ package parser import ( "encoding/xml" - "html" "io" "strings" @@ -58,7 +57,7 @@ func (a *atomText) String() string { if a.Type == "xhtml" { data = a.XML } - return html.UnescapeString(strings.TrimSpace(data)) + return strings.TrimSpace(data) } func (links atomLinks) First(rel string) string { diff --git a/src/parser/atom_test.go b/src/parser/atom_test.go index f47594e..46aa935 100644 --- a/src/parser/atom_test.go +++ b/src/parser/atom_test.go @@ -214,3 +214,19 @@ func TestAtomLinkInID(t *testing.T) { t.Fatalf("\nwant: %#v\nhave: %#v\n", want, have) } } + +func TestAtomDoesntEscapeHTMLTags(t *testing.T) { + feed, _ := Parse(strings.NewReader(` + + + &lt;script&gt;alert(1);&lt;/script&gt; + + `)) + have := feed.Items[0].Content + want := "<script>alert(1);</script>" + if !reflect.DeepEqual(want, have) { + t.Logf("want: %#v", want) + t.Logf("have: %#v", have) + t.FailNow() + } +} From 4a42b239ccfcad48dc7ae1a13e61b641297fe9c9 Mon Sep 17 00:00:00 2001 From: Nazar Kanaev Date: Sun, 16 Jun 2024 11:39:14 +0100 Subject: [PATCH 05/10] update changelog --- doc/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/changelog.txt b/doc/changelog.txt index 5ec4109..ebd9075 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -2,12 +2,14 @@ - (new) Fever API support (thanks to @icefed) - (new) editable feed link (thanks to @adaszko) +- (new) switch to feed by clicking the title in the article page (thanks to @tarasglek for suggestion) - (fix) duplicate articles caused by the same feed addition (thanks to @adaszko) - (fix) relative article links (thanks to @adazsko for the report) - (fix) atom article links stored in id element (thanks to @adazsko for the report) - (fix) parsing atom feed titles (thanks to @wnh) - (fix) sorting same-day batch articles (thanks to @lamescholar for the report) - (fix) showing login page in the selected theme (thanks to @feddiriko for the report) +- (fix) parsing atom feeds with html elements (thanks to @tillcash & @toBeOfUse for the report, @krkk for the fix) # v2.4 (2023-08-15) From 349c966c63ba1a213c837e9c7ced3ac6bbe8486e Mon Sep 17 00:00:00 2001 From: Nazar Kanaev Date: Fri, 21 Jun 2024 10:56:48 +0100 Subject: [PATCH 06/10] sqlite parameters --- .gitignore | 2 ++ src/storage/storage.go | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 84087b4..04c489f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /_output /yarr *.db +*.db-shm +*.db-wal *.syso versioninfo.rc diff --git a/src/storage/storage.go b/src/storage/storage.go index bb5f5ae..25d1c50 100644 --- a/src/storage/storage.go +++ b/src/storage/storage.go @@ -2,6 +2,9 @@ package storage import ( "database/sql" + "log" + "strings" + _ "github.com/mattn/go-sqlite3" ) @@ -10,14 +13,17 @@ type Storage struct { } func New(path string) (*Storage, error) { + if pos := strings.IndexRune(path, '?'); pos == -1 { + params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared" + log.Printf("opening db with params: %s", params) + path = path + "?" + params + } + db, err := sql.Open("sqlite3", path) if err != nil { return nil, err } - // TODO: https://foxcpp.dev/articles/the-right-way-to-use-go-sqlite3 - db.SetMaxOpenConns(1) - if err = migrate(db); err != nil { return nil, err } From b571042c5ddb19d78d66b4b470257fe11487c3ae Mon Sep 17 00:00:00 2001 From: Nazar Kanaev Date: Fri, 21 Jun 2024 12:29:09 +0100 Subject: [PATCH 07/10] change item table index --- src/storage/migration.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/storage/migration.go b/src/storage/migration.go index 9646a97..ec9b7d4 100644 --- a/src/storage/migration.go +++ b/src/storage/migration.go @@ -16,13 +16,16 @@ var migrations = []func(*sql.Tx) error{ m06_fill_missing_dates, m07_add_feed_size, m08_normalize_datetime, + m09_change_item_index, } var maxVersion = int64(len(migrations)) func migrate(db *sql.DB) error { var version int64 - db.QueryRow("pragma user_version").Scan(&version) + if err := db.QueryRow("pragma user_version").Scan(&version); err != nil { + return err + } if version >= maxVersion { return nil @@ -294,3 +297,12 @@ func m08_normalize_datetime(tx *sql.Tx) error { _, err = tx.Exec(`update items set date = strftime('%Y-%m-%d %H:%M:%f', date);`) return err } + +func m09_change_item_index(tx *sql.Tx) error { + sql := ` + drop index if exists idx_item_status; + create index if not exists idx_item__date_id_status on items(date,id,status); + ` + _, err := tx.Exec(sql) + return err +} From f71792d6a50fff98ba6ed17b88b10e4687cae9e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:03:27 +0000 Subject: [PATCH 08/10] Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f5191a..66abc5d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: draft: true prerelease: true - name: Download Artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4.1.7 with: path: . - name: Preparation From 2a4d974965703eafd5f09e3bf5788f684897f877 Mon Sep 17 00:00:00 2001 From: Nazar Kanaev Date: Wed, 25 Sep 2024 11:01:03 +0100 Subject: [PATCH 09/10] go fmt --- src/parser/atom_test.go | 30 +++++++++++++++--------------- src/server/auth/middleware.go | 6 +++--- src/server/routes.go | 2 +- src/storage/item.go | 13 ++++++------- src/storage/migration.go | 8 ++++---- src/storage/storage.go | 8 ++++---- 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/parser/atom_test.go b/src/parser/atom_test.go index 46aa935..88b40a3 100644 --- a/src/parser/atom_test.go +++ b/src/parser/atom_test.go @@ -192,23 +192,23 @@ func TestAtomLinkInID(t *testing.T) { have := feed.Items want := []Item{ Item{ - GUID: "https://example.com/posts/1::2003-12-13T09:17:51", - Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC), - URL: "https://example.com/posts/1", - Title: "one updated", - }, + GUID: "https://example.com/posts/1::2003-12-13T09:17:51", + Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC), + URL: "https://example.com/posts/1", + Title: "one updated", + }, Item{ GUID: "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6", - Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "", - Title: "two", - }, - Item{ - GUID: "https://example.com/posts/1::", - Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), - URL: "https://example.com/posts/1", - Title: "one", - Content: "", - }, + Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "", + Title: "two", + }, + Item{ + GUID: "https://example.com/posts/1::", + Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), + URL: "https://example.com/posts/1", + Title: "one", + Content: "", + }, } if !reflect.DeepEqual(want, have) { t.Fatalf("\nwant: %#v\nhave: %#v\n", want, have) diff --git a/src/server/auth/middleware.go b/src/server/auth/middleware.go index 424878f..1755789 100644 --- a/src/server/auth/middleware.go +++ b/src/server/auth/middleware.go @@ -51,12 +51,12 @@ func (m *Middleware) Handler(c *router.Context) { c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{ "username": username, "error": "Invalid username/password", - "settings": m.DB.GetSettings(), + "settings": m.DB.GetSettings(), }) return } } c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{ - "settings": m.DB.GetSettings(), - }) + "settings": m.DB.GetSettings(), + }) } diff --git a/src/server/routes.go b/src/server/routes.go index eecb2b4..6d05320 100644 --- a/src/server/routes.go +++ b/src/server/routes.go @@ -35,7 +35,7 @@ func (s *Server) handler() http.Handler { Username: s.Username, Password: s.Password, Public: []string{"/static", "/fever"}, - DB: s.db, + DB: s.db, } r.Use(a.Handler) } diff --git a/src/storage/item.go b/src/storage/item.go index 173a213..68c6821 100644 --- a/src/storage/item.go +++ b/src/storage/item.go @@ -79,22 +79,21 @@ type MarkFilter struct { type ItemList []Item func (list ItemList) Len() int { - return len(list) + return len(list) } func (list ItemList) SortKey(i int) string { - return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID + return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID } func (list ItemList) Less(i, j int) bool { - return list.SortKey(i) < list.SortKey(j) + return list.SortKey(i) < list.SortKey(j) } func (list ItemList) Swap(i, j int) { - list[i], list[j] = list[j], list[i] + list[i], list[j] = list[j], list[i] } - func (s *Storage) CreateItems(items []Item) bool { tx, err := s.db.Begin() if err != nil { @@ -104,8 +103,8 @@ func (s *Storage) CreateItems(items []Item) bool { now := time.Now().UTC() - itemsSorted := ItemList(items) - sort.Sort(itemsSorted) + itemsSorted := ItemList(items) + sort.Sort(itemsSorted) for _, item := range itemsSorted { _, err = tx.Exec(` diff --git a/src/storage/migration.go b/src/storage/migration.go index ec9b7d4..1f33967 100644 --- a/src/storage/migration.go +++ b/src/storage/migration.go @@ -16,16 +16,16 @@ var migrations = []func(*sql.Tx) error{ m06_fill_missing_dates, m07_add_feed_size, m08_normalize_datetime, - m09_change_item_index, + m09_change_item_index, } var maxVersion = int64(len(migrations)) func migrate(db *sql.DB) error { var version int64 - if err := db.QueryRow("pragma user_version").Scan(&version); err != nil { - return err - } + if err := db.QueryRow("pragma user_version").Scan(&version); err != nil { + return err + } if version >= maxVersion { return nil diff --git a/src/storage/storage.go b/src/storage/storage.go index 25d1c50..28cccfb 100644 --- a/src/storage/storage.go +++ b/src/storage/storage.go @@ -14,10 +14,10 @@ type Storage struct { func New(path string) (*Storage, error) { if pos := strings.IndexRune(path, '?'); pos == -1 { - params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared" - log.Printf("opening db with params: %s", params) - path = path + "?" + params - } + params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared" + log.Printf("opening db with params: %s", params) + path = path + "?" + params + } db, err := sql.Open("sqlite3", path) if err != nil { From 0cef51c6ac0c7bc37569bee0df673578e739b568 Mon Sep 17 00:00:00 2001 From: Nazar Kanaev Date: Mon, 7 Oct 2024 22:22:56 +0100 Subject: [PATCH 10/10] add sample links --- doc/samples.yml | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 doc/samples.yml diff --git a/doc/samples.yml b/doc/samples.yml new file mode 100644 index 0000000..f6fe777 --- /dev/null +++ b/doc/samples.yml @@ -0,0 +1,64 @@ +- site: https://vimeo.com/channels/staffpicks/videos + feed: https://vimeo.com/channels/staffpicks/videos/rss + tags: [vimeo, image] + +- site: https://www.youtube.com/@everyframeapainting/videos + feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCjFqcJQXGZ6T6sxyFB-5i6A" + tags: [youtube, image] + +- site: https://iwdrm.tumblr.com/ + feed: https://iwdrm.tumblr.com/rss + tags: [tumblr, image] + +- site: https://falseknees.tumblr.com/ + feed: https://falseknees.tumblr.com/rss + tags: [tumblr, image] + +- site: https://accidentallyquadratic.tumblr.com/ + feed: https://accidentallyquadratic.tumblr.com/rss + info: text blog with code sections + tags: [tumblr, text, code] + +- site: https://www.flickr.com/photos/maratsafin/ + feed: https://www.flickr.com/services/feeds/photos_public.gne?id=59021497@N07&lang=en-us&format=atom + tags: [flickr, image] + +- site: https://www.reddit.com/r/comics + feed: https://www.reddit.com/r/comics.rss + tags: [reddit, image] + +- site: https://www.reddit.com/r/AITAH + feed: https://www.reddit.com/r/AITAH.rss + tags: [reddit, text] + +- site: https://idothei.wordpress.com/ + feed: https://idothei.wordpress.com/feed/ + tags: [wordpress, text] + +- site: https://www.vidarholen.net/contents/blog/ + feed: https://www.vidarholen.net/contents/blog/?feed=rss2 + tags: [wordpress, text] + +- site: https://blog.posthaven.com/ + feed: https://blog.posthaven.com/posts.atom + tags: [posthaven, text] + +- site: https://medium.com/@dailynewsletter + feed: https://medium.com/feed/@dailynewsletter + tags: [medium, text] + +- site: https://thereveal.substack.com/ + feed: https://thereveal.substack.com/feed + tags: [substack, text] + +- site: https://tema.livejournal.com/ + feed: https://tema.livejournal.com/data/rss + tags: [livejournal, text] + +- site: https://mametter.hatenablog.com/ + feed: https://mametter.hatenablog.com/feed + tags: [hatena, text] + +- site: https://juliepowell.blogspot.com/ + feed: https://juliepowell.blogspot.com/feeds/posts/default + tags: [blogger, text]