обработку страничек постов вынес из лекс.блока с обработкой главных страничек
parent
761760875f
commit
75f16f65a4
3
main.go
3
main.go
|
@ -51,12 +51,13 @@ func setupRoutes(app *models.App) *http.ServeMux {
|
||||||
router.Handle("/", m(controllers_pages.MainPageHandler(app)))
|
router.Handle("/", m(controllers_pages.MainPageHandler(app)))
|
||||||
// Обработка страницы со списком постов
|
// Обработка страницы со списком постов
|
||||||
router.Handle("/posts/", m(controllers_pages.PostsPageHandler(app)))
|
router.Handle("/posts/", m(controllers_pages.PostsPageHandler(app)))
|
||||||
|
}
|
||||||
|
|
||||||
// Обработка страничек постов
|
// Обработка страничек постов
|
||||||
for key := range app.Posts {
|
for key := range app.Posts {
|
||||||
postLink := string(key)
|
postLink := string(key)
|
||||||
router.Handle(postLink, m(controllers_pages.PostPageHandler(app)))
|
router.Handle(postLink, m(controllers_pages.PostPageHandler(app)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# Тест блоков с кодом!
|
|
||||||
|
|
||||||
Тестовый блок с кодом:
|
|
||||||
|
|
||||||
```
|
|
||||||
// Ответ на метод COUNT
|
|
||||||
#include <stdio.h>
|
|
||||||
int main() {
|
|
||||||
printf("very long striiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -7,6 +7,66 @@
|
||||||
|
|
||||||
Но в реальности все не так просто и при попытке что то положить по вычисленному адресу программа упадет с *segmentation fault (SIGSEGV)*. Чтобы этого избежать, предварительно надо выдать права на запись в страничку памяти где находится целевая строка. Сделать это можно через системные вызовы.
|
Но в реальности все не так просто и при попытке что то положить по вычисленному адресу программа упадет с *segmentation fault (SIGSEGV)*. Чтобы этого избежать, предварительно надо выдать права на запись в страничку памяти где находится целевая строка. Сделать это можно через системные вызовы.
|
||||||
|
|
||||||
Код с пояснениями можно скачать [тут](https://git.hikan.ru/serr/unsafe-change-string-go)
|
```
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := "hello"
|
||||||
|
fmt.Println("Original:", s)
|
||||||
|
|
||||||
|
// Строки в Go - структуры с двумя полями: указатель на данные и длина
|
||||||
|
// тут строка интерпретируется как структура
|
||||||
|
strHeader := (*struct {
|
||||||
|
data unsafe.Pointer
|
||||||
|
len int
|
||||||
|
})(unsafe.Pointer(&s))
|
||||||
|
|
||||||
|
// Вычисляем начало страницы памяти
|
||||||
|
pageSize := syscall.Getpagesize()
|
||||||
|
pageStart := uintptr(strHeader.data) - (uintptr(strHeader.data) % uintptr(pageSize))
|
||||||
|
fmt.Printf(
|
||||||
|
"\nАдрес строки = %d\nразмер страницы памяти = %d\nадрес строки относительно начала страницы = %d\nадрес страницы = %d\n\n",
|
||||||
|
uintptr(strHeader.data),
|
||||||
|
uintptr(pageSize),
|
||||||
|
(uintptr(strHeader.data) % uintptr(pageSize)),
|
||||||
|
pageStart)
|
||||||
|
|
||||||
|
// Имея адрес страницы и ее размер даю права на запись на данной странице памяти
|
||||||
|
ret, _, err := syscall.Syscall(
|
||||||
|
syscall.SYS_MPROTECT,
|
||||||
|
pageStart,
|
||||||
|
uintptr(pageSize),
|
||||||
|
uintptr(syscall.PROT_READ|syscall.PROT_WRITE),
|
||||||
|
)
|
||||||
|
if ret != 0 {
|
||||||
|
panic("mprotect failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Теперь можно менять строку
|
||||||
|
// поменяю, например, пятый байт
|
||||||
|
fifthBytePtr := (*byte)(unsafe.Pointer(uintptr(strHeader.data) + 4))
|
||||||
|
*fifthBytePtr = 0
|
||||||
|
|
||||||
|
// Восстанавливаю дефолтные права
|
||||||
|
ret, _, err = syscall.Syscall(
|
||||||
|
syscall.SYS_MPROTECT,
|
||||||
|
pageStart,
|
||||||
|
uintptr(pageSize),
|
||||||
|
uintptr(syscall.PROT_READ),
|
||||||
|
)
|
||||||
|
if ret != 0 {
|
||||||
|
panic("mprotect restore failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Modified:", s) // Должно быть "hell"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Тестил на **go version go1.22.2 linux/amd64**
|
Тестил на **go version go1.22.2 linux/amd64**
|
Loading…
Reference in New Issue