00:05 <+bridge_> was I pinged ๐Ÿ‘€? can't find the message 00:06 <+bridge_> hm, it's melon's message, found it. 00:24 <+bridge_> This years 38C3 meetup: https://events.ccc.de/congress/2024/hub/event/ddnetteeworlds-meetup/ 00:24 <+bridge_> If any of you ever want to install windows on a usb disk, you can do it quite easily with dism, very enjoyable process 00:50 <+bridge_> like as in creating a bootable usb? 00:52 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486513166962655363/image.png?ex=69c5c6c5&is=69c47545&hm=610fb97e5902d3a9ee59bae8cc8e7611e91f0d2ed5e1d2b7c2de8787caa3162c& 00:53 <+bridge_> where is it on mobile app? 00:53 <+bridge_> huh since when does windows allow itself to be installed onto external devices? 00:53 <+bridge_> found it D: 00:54 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486513713140859003/image0.png?ex=69c5c747&is=69c475c7&hm=b927979236ff5d20d0d0c230e30a3de9217a72b526b5e88203d13742a2b59a84& 01:05 <+bridge_> Hehehe get pinged 01:06 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486516774420615198/image0.gif?ex=69c5ca21&is=69c478a1&hm=9b7b6e24566fd8806a989b4871ced6ecb6d889e013b2658939e4e6aeca90bc0c& 01:08 <+bridge_> it's an artificial restriction, you can avoid it by - as learath mentioned using dism 01:08 <+bridge_> 01:08 <+bridge_> There are also modified Installations to bypass it afaik 01:24 <+bridge_> the official windows 10 installer offer me to make a bootable usb last time I used it 01:24 <+bridge_> the official windows 10 installer offered me to make a bootable usb last time I used it 01:25 <+bridge_> actually I think you can just boot off of any windows 10 install usb 01:25 <+bridge_> I recall that also being a thing 01:29 <+bridge_> Yeah 01:30 <+bridge_> It doesn't that's why you apply the image onto the partition with dism directly, it's just the installer that doesn't allow it 09:20 <+bridge_> yeah, it's here 09:20 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486641028340650014/image.png?ex=69c63dd9&is=69c4ec59&hm=58553589768afb566c95ab50ca592e343ddfe66d7d8844108cc411000488f89f& 12:14 <+bridge_> @learath2 do C and C++ have different rules wrt. reinterpreting memory? 12:15 <+bridge_> I might have applied the wrong rules the whole time, then 12:20 <+bridge_> @chillerdragon why u ping me on random commits in github lol 12:20 <+bridge_> xD 12:20 <+bridge_> i wont play gores ddnet is better 12:22 <+bridge_> @einfach_henriiik btw maybe this interests u for ddnet security 12:22 <+bridge_> https://www.cisa.gov/news-events/alerts/2025/03/18/supply-chain-compromise-third-party-tj-actionschanged-files-cve-2025-30066-and-reviewdogaction 12:22 <+bridge_> u should pin all ur github actions to their hash isntead of using version tags (v2, v3, etc) to avoid this kind of supply chain attack 12:23 <+bridge_> an attacker can change the versioned code 12:23 <+bridge_> but the hash is immutable 12:25 <+bridge_> They are similar, do you have something specific you had in mind that you might be misunderstanding? 12:30 <+bridge_> If you are talking about my comment about lifetime, I did browse around the standard a little, and I think you do get away with it since both types are `implicit-lifetime types` and beginning the lifetime of an `unsigned char` array is allowed to start implicit lifetimes (I forgot this part). 12:35 <+bridge_> The aliasing one idk if you get away with, that part of the standard is just a little too dense, maybe you do? Idk couldn't make certain 12:40 <+bridge_> who is @einfach_henriiik? ^^ I can't find any messages from them. hmm. was that supposed to go to me? I see a substring "henri" in there ^^ 12:41 <+bridge_> oh damn 12:41 <+bridge_> yeah idk who that is lmao 12:41 <+bridge_> @heinrich5991 btw maybe this interests u for ddnet security 12:41 <+bridge_> https://www.cisa.gov/news-events/alerts/2025/03/18/supply-chain-compromise-third-party-tj-actionschanged-files-cve-2025-30066-and-reviewdogaction 12:41 <+bridge_> u should pin all ur github actions to their hash isntead of using version tags (v2, v3, etc) to avoid this kind of supply chain attack 12:41 <+bridge_> fixed 12:42 <+bridge_> ah, now your message is without context. meh 12:42 <+bridge_> feel fre to delete 12:42 <+bridge_> ๐Ÿ˜„ 12:42 <+bridge_> we can't really have supply chain attacks in github actions. they can't take any actions 12:42 <+bridge_> AFAIK, at least 12:43 <+bridge_> which is our security model for github actions 12:43 <+bridge_> do we have any secrets? 12:43 <+bridge_> no 12:43 <+bridge_> ah then its fine 12:43 <+bridge_> Well they do create artifacts that people do use 12:43 <+bridge_> the power of deen releases 12:43 <+bridge_> Perhaps you could poison an artifact somehow? 12:43 <+bridge_> is nightly done by deen too 12:43 <+bridge_> ? 12:43 <+bridge_> yes 12:44 <+bridge_> true, they could poison artifacts 12:48 <+bridge_> in C, I can freely cast between `char *` and any one other single type 12:48 <+bridge_> and in C, I can use a struct pointer as a pointer to the first element 12:48 <+bridge_> there's nothing about "starting lifetimes" there 12:49 <+bridge_> (there isn't any placement `new` either) 12:49 <+bridge_> Yeah, C doesn't have lifetimes. But I think the lifetime you do get away with anyway. C++20 did make it defined behaviour and they retroactively applied it to all previous standards. Creating that unsigned char array does start lifetimes properly now 12:49 <+bridge_> (note that I didn't make anything worse there, it's the same as before. but if there's anything worse fixing wrt. the standard, we can do it now that we look at the code) 12:50 <+bridge_> (note that I didn't make anything worse there, it's the same as before. but if there's anything worse, fixing wrt. the standard, we can do it now that we look at the code) 12:50 <+bridge_> (note that I didn't make anything worse there, it's the same as before. but if there's anything worth fixing wrt. the standard, we can do it now that we look at the code) 12:50 <+bridge_> ah nice, probably to allow C-style code to be okay? 12:51 <+bridge_> The cast idk, I think it's UB, there is technically a chain of casts that does make it legal, but that's not how the c style cast will end up being evaluated as 12:51 <+bridge_> ah, you mean intermediate casts have value for the standard? 12:51 <+bridge_> I can make it use `m_aData` I guess 12:51 <+bridge_> then we don't have to language lawyer it 12:53 <+bridge_> Yeah I think that's for the best. Perhaps there is some language somewhere that does make it defined but I really can't remember off the top of my head 12:53 <+bridge_> Nor could I find it yesterday 12:55 <+bridge_> annoying that the new PR diff "experience" is so much worse than before 12:55 <+bridge_> I guess you're not supposed to look at diffs 12:55 <+bridge_> Like the correct chain is something like static cast to `unsigned char *` relying on the standard layout of the object, then a static cast to `CSnapshot *` and that should be ok(tm) 12:55 <+bridge_> Yeah, just ask AI 12:56 <+bridge_> Like the correct chain is something like static cast to `void *` then to `unsigned char *` relying on the standard layout of the object, then a static cast to `CSnapshot *` and that should be ok(tm) 12:56 <+bridge_> I really struggled with this too, it's so bad especially with massive diffs 12:57 <+bridge_> Even if you hide the massive files 13:03 <+bridge_> Yes, it was informally being used by everyone anyway, so the compilers were already treating it almost as if it was defined behaviour 13:03 <+bridge_> https://clang.llvm.org/extra/clang-tidy/checks/bugprone/casting-through-void.html :monkaS: 13:06 <+bridge_> most notably C allows type punning through unions while C++ doesn't 13:06 <+bridge_> does C allow that? 13:06 <+bridge_> is that a new rule? 13:06 <+bridge_> Yeah, but unless there is some language somewhere in the standard that says `reinterpret_cast` can be used whenever there exists a valid chain of other casts, I don't think you can omit it 13:06 <+bridge_> It has been a footnote since C99, type punning is legal 13:07 <+bridge_> I'll admit that I don't know the standard by heart there but that's what I remember reading from secondary sources, e.g. 13:07 <+bridge_> Footnote 106 in C23 13:07 <+bridge_> this should be fine in C++ too 13:08 <+bridge_> my understanding is that the C++ standard does not mandate anything about which *casts* are legal, just about what pointers of what types can be dereferenced 13:08 <+bridge_> If and only if the class/struct is of standard layout (`std::is_standard_layout`) 13:08 <+bridge_> so you wouldn't need to cast through `void *` 13:08 <+bridge_> yeah 13:09 <+bridge_> I don't know what review comment this is about, though 13:09 <+bridge_> Well a pointer produced by `reinterpret_cast` is only legal to dereference under certain circumstances 13:10 <+bridge_> yes 13:10 <+bridge_> in my model, nothing matters except the actual type living at an address 13:10 <+bridge_> what I mean is, the sequence of casts to produce a pointer should not matter 13:10 <+bridge_> and that's definitely true for `const` casts 13:10 <+bridge_> just the type of the pointer and the actual type of the object pointed to 13:10 <+bridge_> what I mean is, the sequence of casts used to produce a pointer should not matter 13:10 <+bridge_> i.e. `CSnapshot` and `char m_aData[65536]` both live at that address 13:11 <+bridge_> i.e. `CSnapshotBuffer` and `char m_aData[65536]` both live at that address 13:11 <+bridge_> hence it's fine to case the pointer (wherever it was obtained from) to `CSnapshot` 13:11 <+bridge_> (that mental model is where my code comes from) 13:11 <+bridge_> ``` 13:11 <+bridge_> class CSnapshot; 13:11 <+bridge_> class CSnapshotBuffer { 13:11 <+bridge_> unsigned char m_Buf[MAX_SIZE]; 13:11 <+bridge_> }; 13:11 <+bridge_> 13:11 <+bridge_> CSnapshotBuffer *pBuffer = malloc(sizeof(*pBuffer)); 13:11 <+bridge_> CSnapshot *pSnap = (CSnapshot *)pBuffer; 13:11 <+bridge_> ``` 13:12 <+bridge_> actually without that `malloc` 13:12 <+bridge_> ```c++ 13:12 <+bridge_> class CSnapshot; 13:12 <+bridge_> class CSnapshotBuffer { 13:12 <+bridge_> unsigned char m_Buf[MAX_SIZE]; 13:12 <+bridge_> }; 13:12 <+bridge_> 13:13 <+bridge_> CSnapshotBuffer Buffer; 13:13 <+bridge_> CSnapshot *pSnap = (CSnapshot *)&pBuffer; 13:13 <+bridge_> ``` 13:13 <+bridge_> ```c++ 13:13 <+bridge_> class CSnapshot; 13:13 <+bridge_> class CSnapshotBuffer { 13:13 <+bridge_> unsigned char m_Buf[MAX_SIZE]; 13:13 <+bridge_> }; 13:13 <+bridge_> 13:13 <+bridge_> CSnapshotBuffer Buffer; 13:13 <+bridge_> CSnapshot *pSnap = (CSnapshot *)&Buffer; 13:13 <+bridge_> ``` 13:14 <+bridge_> what's the question? 13:14 <+bridge_> is that legal, if you access data through `pSnap`? 13:15 <+bridge_> Here is why I think that's UB (note that I'm not saying it'll ever break in any implementation, just UB per the standard): 13:15 <+bridge_> - That c style cast will end up evaluating to a `reinterpret_cast` 13:15 <+bridge_> - The resulting reference can thus be only accessed safely if the reference type is similar to `char` or `unsigned char` or if it's similar to `CSnapshot` 13:15 <+bridge_> - It's not similar to any, so that pointer can't be dereferenced 13:15 <+bridge_> ```c++ 13:15 <+bridge_> class CSnapshot; 13:15 <+bridge_> class alignas(CSnapshot) CSnapshotBuffer { 13:15 <+bridge_> unsigned char m_Buf[MAX_SIZE]; 13:15 <+bridge_> }; 13:15 <+bridge_> 13:15 <+bridge_> CSnapshotBuffer Buffer; 13:15 <+bridge_> CSnapshot *pSnap = (CSnapshot *)&Buffer; 13:15 <+bridge_> ``` 13:16 <+bridge_> However, there does exist a chain of casts that will produce a pointer that is definitely allowed to be dereferenced. It's just not what this c style cast will boil down to 13:17 <+bridge_> that definitely allowed sequence would be `CSnapshot *pSnap = (CSnapshot *)(unsigned char *)&Buffer;` 13:18 <+bridge_> welcome to C++ language lawyering for stuff that actually appears in projects ๐Ÿ˜ฎ 13:18 <+bridge_> barring questions about lifetimes, I'd think it's legal 13:19 <+bridge_> through some combination of "anything is type-accessible through char pointers" and common initial sequence rules 13:19 <+bridge_> lifetimes are fine, I checked that one pretty thoroughly, both types can start their lifetimes implicitly, and just allocating that array is allowed to start lifetimes nowadays 13:19 <+bridge_> but, naturally, if you have to spend more than two minutes digging through the standard to know whether it's allowed you probably shouldn't use it 13:19 <+bridge_> there's uhh 13:19 <+bridge_> They don't share a common initial sequence 13:19 <+bridge_> `std::as_mutable_bytes` and friends 13:19 <+bridge_> that might help 13:20 <+bridge_> err 13:20 <+bridge_> `std::as_writable_bytes` 13:21 <+bridge_> hmm yeah you may be right 13:21 <+bridge_> the proposed alternative was `CSnapshot *pSnap = (CSnapshot *)Buffer.m_aBuf;` 13:21 <+bridge_> since that sequence requires members to match one-by-one 13:21 <+bridge_> that's just as good for semantics, so I'm just going to use that 13:21 <+bridge_> that sounds better 13:22 <+bridge_> Which is tbf just fine aswell, I'm just curious now ๐Ÿ˜„ 13:22 <+bridge_> I might ask this later in the C++ irc to see what the language lawyers think 13:22 <+bridge_> They did add a lot of "if such and such would make the behaviour defined, then it behaves like that" language in C++20 13:22 <+bridge_> Maybe one of those covers this 13:27 <+bridge_> this goes against my mental model though, so perhaps the mental model is wrong for type casting (but not for `const` casting) 13:28 <+bridge_> (and it would mean that intermediate casts do something) 13:28 <+bridge_> which is also weird IMO 13:28 <+bridge_> ...right 13:29 <+bridge_> you would expect to be able to cast a `CSnapshot *` to an `unsigned char *` 13:29 <+bridge_> *that* would work due to initial sequence rules 13:30 <+bridge_> ....but no, wait 13:30 <+bridge_> intermediate casts do do something, in that sense 13:30 <+bridge_> as in, the relation "A can be legally accessed through a pointer to B" is not transitive 13:31 <+bridge_> hmmm 13:32 <+bridge_> yes, of course that doesn't apply 13:32 <+bridge_> because you can cast everything to a char pointer 13:32 <+bridge_> and a char object can be accessed through any pointer 13:32 <+bridge_> but intermediate casts don't fix this 13:32 <+bridge_> so the two sentences are rather unrelated to each other 13:33 <+bridge_> I guess you mean `CSnapshotBuffer *`, (well you can cast anything to `unsigned char *` but not due to initial sequence rules) 13:34 <+bridge_> you would expect to be able to cast ~~a `CSnapshot *`~~ a `CSnapshotBuffer *` to an `unsigned char *` 13:34 <+bridge_> yeah 13:37 <+bridge_> wait do the common initial sequence rules only apply to unions and not to pointer-based type punning? 13:37 <+bridge_> I'm pretty sure you can cast a struct pointer to a pointer to its initial member 13:37 <+bridge_> I used to believe otherwise but if I read the (C++20 final draft) standard correctly that seems to be the case 13:38 <+bridge_> You can, but I don't think it's due to common initial sequence rules 13:39 <+bridge_> yeah 13:39 <+bridge_> I think it's per C++20 11.4p26 which says standard layout objects are pointer interconvertible to their first member 13:39 <+bridge_> looks like that's the concept of `pointer-interconvertible` 13:39 <+bridge_> yeah 13:39 <+bridge_> I think it's per C++20 11.4p26 which says standard layout objects are pointer interconvertible to a pointer to their first member 13:39 <+bridge_> I think it's per C++20 11.4p26 which says standard-layout objects are pointer interconvertible to a pointer to their first member 13:39 <+bridge_> (iff there are no non static data members that are non standard-layout) 13:40 <+bridge_> nvm 13:40 <+bridge_> So you are allowed to do `static_cast(&Buffer)` 100% 13:41 <+bridge_> `reinterpret_cast`* 13:41 <+bridge_> actually 13:42 <+bridge_> > Note: An array object and its first element are not pointer-interconvertible, even though they have the same address 13:42 <+bridge_> but idk yet what exactly this entails 13:42 <+bridge_> No `static_cast` 13:43 <+bridge_> is there a sanitizer that catches all UB? 13:43 <+bridge_> we could just try it out in that case 13:43 <+bridge_> Wait no, it is `reinterpret_cast` hm 13:43 <+bridge_> (for rust, there's miri which does this) 13:44 <+bridge_> I had just finished writing my toy example 13:44 <+bridge_> (either way I'd just recommend this) 13:44 <+bridge_> if feasible 13:45 <+bridge_> Hahaha, fun-fact: An array object and its first element are not pointer-interconvertible, even though they have the same address. 13:45 <+bridge_> โ™ป๏ธ 13:45 <+bridge_> but yes 13:45 <+bridge_> repost 13:45 <+bridge_> Ah, missed it 13:45 <+bridge_> not applicable, we do other weird stuff 13:46 <+bridge_> that's probably UB 13:46 <+bridge_> but it's fine, because I haven't touched it ๐Ÿ˜› 13:46 <+bridge_> You know what else is UB? We accessing way past that `CSnapshot` object 13:46 <+bridge_> ^ 13:46 <+bridge_> Though tbf under the new implicit lifetime rules at least the lifetimes are A-OK ๐Ÿ˜„ 13:50 <+bridge_> @learath2 wrt. `rust::Slice`/`rust::Box`: I'd treat them like we treat `std::unique_ptr` etc., i.e. not as an implementation detail but as something that every interface can use 13:51 <+bridge_> I think someone named such types "vocabulary types" 13:52 <+bridge_> oh wait @learath2: you haven't looked at/reviewed https://github.com/ddnet/ddnet/pull/11913 yet 13:53 <+bridge_> or rather, you might have looked at that as part of the rust snapshot PR 13:53 <+bridge_> I looked at the entire other PR so I reviewed this part too 13:53 <+bridge_> ah nice 13:54 <+bridge_> so I'll fix the `CSnapshotBuffer` there and can press the merge button? 13:55 <+bridge_> (or rather, I've fixed it now and maybe you can merge it) 13:56 <+bridge_> Do we want that is the question, I don't really know anything about the semantics of these things within C++ code, is this something we all need to learn now? 13:57 <+bridge_> `rust::Box` behaves like `std::unique_ptr`, `rust::Slice` behaves like `std::span` 13:57 <+bridge_> Did you look at your TODOs aswell? Assuming they will stay there forever, are they okay to stay? 13:57 <+bridge_> they expose a very C++y interface 13:57 <+bridge_> .........but then again 13:58 <+bridge_> now I don't actually think the pointer aliasing rules have *anything* to do with either common initial sequences or pointer-interconvertibility 13:58 <+bridge_> uhm, I meant https://github.com/ddnet/ddnet/pull/11913. that one doesn't have any TODOs 13:59 <+bridge_> I still want to add some docs to the rust PR 13:59 <+bridge_> most of the TODOs are things I just noticed being wrong about the old code btw. e.g. the missing alignment 13:59 <+bridge_> pointer-interconvertibility is what makes the conversion possible at all, access through it is valid because `unsigned char` is allowed to alias everything 13:59 <+bridge_> Oh this one is good to go yeah 13:59 <+bridge_> Let me merge it 14:00 <+bridge_> I think the conversion is just always possible 14:00 <+bridge_> > An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of 14:00 <+bridge_> > object pointer type is converted to the object pointer type โ€œpointer to cv Tโ€, the result is static_cast > T*>(static_cast(v)). 14:00 <+bridge_> so yes, this is something everyone would need to learn. `rust::Box` behaves like `std::unique_ptr`, `rust::Slice` behaves like `std::span` 14:02 <+bridge_> and all the standard says about *accessing* values through the pointers is 14:02 <+bridge_> > If a program attempts to access (3.1) the stored value of an object through a glvalue whose type is not 14:02 <+bridge_> > similar (7.3.5) to one of the following types the behavior is undefined:51 14:02 <+bridge_> > โ€”(11.1) the dynamic type of the object, 14:02 <+bridge_> > โ€”(11.2) a type that is the signed or unsigned type corresponding to the dynamic type of the object, or 14:02 <+bridge_> > โ€”(11.3) a char, unsigned char, or std::byte type. 14:02 <+bridge_> but, notably, this does not actually refer to the pointer type but to the type of the glvalue 14:04 <+bridge_> ... but then this would mean that you cannot initialize a char buffer and access it through a pointer to some class 14:05 <+bridge_> but you can go vice-versa 14:05 <+bridge_> AFAIK that's legal though 14:05 <+bridge_> or, at least, this section of the standard does not say that going vice-versa is UB 14:06 <+bridge_> btw, vocabulary types: https://enimihil.net/vocabulary-types 14:07 <+bridge_> maybe there are some rules about implicit object creation that save this 14:08 <+bridge_> Yes, that does save it 14:09 <+bridge_> and if they do then I think the originally posted code is legal 14:09 <+bridge_> @heinrich5991 off topic question but do u think rust would have been as famous using a linear type system instead of affine 14:09 <+bridge_> As long as the type is an `implicit-lifetime type` 14:09 <+bridge_> which I assume POD types are? 14:09 <+bridge_> Yes 14:10 <+bridge_> Why though? If it was casting the `unsigned char *` to the array itself directly, I agree 14:11 <+bridge_> though by that reasoning dereferencing any reinterpret_cast, no matter if from a char array or not, to an implicit lifetime object would be legal 14:12 <+bridge_> why? 14:12 <+bridge_> ```c++ 14:12 <+bridge_> int x; 14:12 <+bridge_> *(float *)&x = 0; 14:12 <+bridge_> ``` 14:12 <+bridge_> is illegal AFAIK 14:13 <+bridge_> Mh, maybe we are just not that good at this language lawyering thing ๐Ÿ˜„ 14:13 <+bridge_> ah 14:13 <+bridge_> > An operation that begins the lifetime of an array of char, unsigned char, or std::byte implicitly creates 14:13 <+bridge_> > objects within the region of storage occupied by the array 14:13 <+bridge_> Though tbf my specialty is C, not C++ 14:13 <+bridge_> i think in c its legal 14:14 <+bridge_> yeah then I think we're fine 14:14 <+bridge_> creating a `CSnapshotBuffer` begins the lifetime of its `buf` array which implicitly creates objects inside it, and you can hence access that object through a pointer to it 14:15 <+bridge_> We'd resolved that before though 14:15 <+bridge_> The question is whether the pointer created through that C style cast is even allowed to be dereferenced 14:17 <+bridge_> https://en.cppreference.com/w/cpp/numeric/bit_cast.html i think this is zero cost 14:17 <+bridge_> I think it is, or at least the type-based aliasing rule does not prevent it 14:18 <+bridge_> `pSnap` is a `CSnapshot *`, so `*pSnap` is a glvalue of type `CSnapshot` pointing to an implicitly created object 14:18 <+bridge_> if I understand these implicit creation rules correctly 14:22 <+bridge_> But the issue is that I don't see how you argue that the pointer is really pointing to the unsigned char buffer. I mean it obviously is, but mh. I guess maybe that's where the pointer-interconvertibility helps? 14:23 <+bridge_> Because for all the type system knows technically `pSnap` is a `CSnapshot *` which is pointing to a `CSnapshotBuffer`, it's aliasing a type that is not similar to any of the allowed 3 categories 14:24 <+bridge_> as is using `memcpy` for the purpose of `std::bitcast`. it doesn't help us here though 14:24 <+bridge_> (ah, it even shows `memcpy` in the possible implementation)) 14:24 <+bridge_> (ah, it even shows `memcpy` in the possible implementation) 14:29 <+bridge_> ok yeah I don't yet understand the semantics of "what does a static_casted pointer point to" 14:29 <+bridge_> Aaaaah, enough. I need to study an actual language for I have a Dutch exam in a couple hours 14:30 <+bridge_> but I think you'd have the same issue when casting the pointer to the char array? pointer-interconvertibility wouldn't help there either 14:30 <+bridge_> implying that dutch is a real language 14:30 <+bridge_> but good luck 14:31 <+bridge_> Well pointer-interconvertibility does guarantee that the pointers are the same exact value for those two objects 14:31 <+bridge_> baited to not do dutch learning again, apparently 14:31 <+bridge_> but are those pointer-inconvertible? 14:31 <+bridge_> TIL https://en.cppreference.com/w/cpp/utility/launder.html 14:32 <+bridge_> A standard layout object pointer is pointer-interconvertible to a pointer to it's first member 14:32 <+bridge_> ```cpp 14:32 <+bridge_> alignas(float) unsigned char buf[sizeof(float)] = {}; 14:32 <+bridge_> float* f = std::launder(reinterpret_cast(buf)); 14:32 <+bridge_> // f points to a float whose lifetime has begun implicitly 14:32 <+bridge_> *f = 1.0f; // well-defined 14:32 <+bridge_> ``` 14:32 <+bridge_> :justatest: 14:33 <+bridge_> So reinterpret_cast will return a pointer that is valid to be dereferenced for that unsigned char array 14:33 <+bridge_> After that casting it to another object type is justified by implicit object creation 14:33 <+bridge_> yeah pretty much this 14:33 <+bridge_> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0593r6.html 14:33 <+bridge_> heinrich says that that code would be legal without the launder call 14:34 <+bridge_> and if that's legal then I'd expect the snapshot code to be legal too 14:34 <+bridge_> EEEEH, launder is not really applicable here with standard layout objects that don't inherit from anything 14:35 <+bridge_> Well maybe actually relevant 14:35 <+bridge_> that should be legal without `std::launder` 14:35 <+bridge_> AAAAAA 14:36 <+bridge_> i think without launder u break pointer provenance but maybe im wrong 14:36 <+bridge_> where's that code from? did you just write it yourself or was there surrounding text? 14:36 <+bridge_> the thing is that accessing `char` arrays through another pointer is not UB AFAIK 14:36 <+bridge_> (and also accessing other objects through `char` pointers) 14:37 <+bridge_> it's illegal to access an `int` through a `float` pointer though 14:39 <+bridge_> i think ur right 14:39 <+bridge_> https://eel.is/c++draft/basic.lval#11 14:40 <+bridge_> being a expert in c/c++ feels like being a lawyer 14:41 <+bridge_> yeah this says that you can access anything through a `char *` 14:42 <+bridge_> the question is whether you can access `char` arrays through `Foo *` 14:42 <+bridge_> This is (IMHO) legal without launder 14:43 <+bridge_> For unsigned char arrays whose lifetime has begun, this is also legal. It's the jump from the class to it's first member that I can't exactly justify 14:43 <+bridge_> oh I get your question now 14:43 <+bridge_> does not using launder allow some optmizations? 14:43 <+bridge_> Some illegal ones, yes. The compiler can assume the dynamic type of an object hasn't changed 14:43 <+bridge_> Some dangerous ones, yes. The compiler can assume the dynamic type of an object hasn't changed 14:44 <+bridge_> So when devirtualizing it can use the old dynamic type if you craft a new object in there 14:44 <+bridge_> if I understand you correctly, `reinterpret_cast(static_cast(&Buffer))` should be legal? 14:44 <+bridge_> unsigned char * and both need to be reinterpret casts, but yes 14:45 <+bridge_> I made the second one a static_cast because that's where pointer-interconvertibility should then guarantee that the `char (*) [MAX_SIZE]` points to `Buffer.buf` 14:45 <+bridge_> I made the second one a static_cast because that's where pointer-interconvertibility should then guarantee that the `char (*) [MAX_SIZE]` points to `Buffer.m_buf` 14:45 <+bridge_> You can't though ๐Ÿ˜› 14:45 <+bridge_> I misread that part too at the start 14:46 <+bridge_> It has to still be a reinterpret_cast 14:46 <+bridge_> I made the second one a static_cast because that's where pointer-interconvertibility should then guarantee that the `unsigned char (*) [MAX_SIZE]` points to `Buffer.m_buf` 14:46 <+bridge_> Ok, I really need to stop this and look at Dutch 14:46 <+bridge_> Bye for now 14:47 <+bridge_> ah 14:47 <+bridge_> yes 14:47 <+bridge_> now I'm where you were an hour ago 14:48 <+bridge_> @learath2 I'd suggest putting your phone in airplane mode if you actually want to study ^^ 14:48 <+bridge_> you seem to be unable to not read this channel ๐Ÿ˜‰ 14:49 <+bridge_> You know I'm addicted to language lawyering 14:51 <+bridge_> maybe you're rather addicted to "not studying" ๐Ÿ˜„ 15:11 <+bridge_> lazy bum! 15:15 <+bridge_> Im funny 15:17 <+bridge_> If the hash is too short it can be cracked 15:17 <+bridge_> Giving a false sense of security 15:20 <+bridge_> true, theoretically, sha1 is known broken 15:21 <+bridge_> so an attacker with enough resources could replace commit content. but github won't allow that 15:21 <+bridge_> also, I learned at FOSDEM that git doesn't use sha1, it uses sha1withoutknowncollisions 15:21 <+bridge_> what does that mean 15:21 <+bridge_> modified algo? 15:21 <+bridge_> which is sha1 unless the input looks like a known collision, in which case it's the truncated sha256 instead 16:39 <+bridge_> https://github.com/cr-marcstevens/sha1collisiondetection 19:38 <+bridge_> Hey guys, is client-side snap tap allowed or not? I just saw there was a huge discussion about this and I didn't get it. Or is it like 50/50? 19:38 <+bridge_> Hellou :3 19:55 <+bridge_> https://github.com/ddnet/ddnet/issues/11861 needs-discussion 19:55 <+bridge_> if you want it to be added state ur opinions in this issue 19:57 <+bridge_> i must have missed this issue, ive never seen it called "contrary direction" 19:58 <+bridge_> yea idk blame @gorp_tw she told me to name it that 20:27 <+bridge_> Well, if I do this in my client, will it be considered a normal function? It should be, yes (I think) 20:27 <+bridge_> dont ask me, im not an admin 20:27 <+bridge_> ๐Ÿ˜„ 20:28 <+bridge_> https://discord.com/channels/252358080522747904/1346788007142756403/1477647664311963650 20:34 <+bridge_> idk if this is input manipulation thoughj 20:34 <+bridge_> my keyboard works like that by default :kek: 20:34 <+bridge_> idk if this is input manipulation though 20:35 <+bridge_> It is. Using the function with a keyboard is also cheating. 21:08 <+bridge_> is it really manipulating input? playing on a controller with an analog stick allows you to switch directions exactly the same on how snaptap works 21:10 <+bridge_> is it really manipulating input in a way where the ddnet client doesnt support? playing on a controller with an analog stick allows you to switch directions exactly the same on how snaptap works 21:10 <+bridge_> some keyboards have an analog stick on it aswell would that be classified as cheating to use? 21:17 <+bridge_> I guess that's hardware level 21:18 <+bridge_> But controllers aren't keyboards. 21:19 <+bridge_> If that part works like a controller than using it as a controller is allowed 21:20 <+bridge_> i have controller similar to this, with arrow keys 21:20 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486822128903782410/image.png?ex=69c6e683&is=69c59503&hm=7d4ae468dc3c6724fb691675401d3865a917dca7ba84a276f32d3089b90f9ad9& 21:20 <+bridge_> and this "snaptap" is built in 21:20 <+bridge_> so what is the issue with snaptap? 21:20 <+bridge_> if it was really an advantage everyone would play on controller 21:21 <+bridge_> the only issue that i can see is that its illegal 21:21 <+bridge_> We have to have some definition of cheating 21:21 <+bridge_> Controllers are controllers and keyboard are keyboards. 21:21 <+bridge_> And patches for things are bad 21:21 <+bridge_> yes i understand that 21:22 <+bridge_> using a controller for movement gives you the same minimal advantage that a keyboard has so why not just allow snaptap 21:23 <+bridge_> If the advantage is so minimum why not just keep the current rules 21:24 <+bridge_> I doubt this because I think playing with controller is already harder and more limited than when playing with keyboard and mouse 21:25 <+bridge_> my controller has keyboard keys 21:25 <+bridge_> so its the same 21:25 <+bridge_> yes that is true you are less precise with a analog stick than a keyboard 21:26 <+bridge_> snaptap just makes it easier to explain what you want direction you want your tee to move exactly the same as having a lighter mouse 21:26 <+bridge_> snaptap just makes it easier to explain to the game what you want direction you want your tee to move exactly the same as having a lighter mouse 21:27 <+bridge_> Aimbot makes it easier to tell the game where you want to hook 21:27 <+bridge_> There are always going to be legal speak arguments abt the rules because u can make an argument for anything. 21:28 <+bridge_> i guess you make a fair point but its not the same 21:29 <+bridge_> For now. What if mice came with integrated aimbot in the firmware? 21:29 <+bridge_> well that would be cheating 21:29 <+bridge_> Same as any input manipulation 21:30 <+bridge_> aimbot is related to the game, this just changes how keys are registered 21:30 <+bridge_> imo this is closer to mouse with infinite scroll 21:30 <+bridge_> Mouse with tas firmware 21:31 <+bridge_> what about magnetic keyboards? 21:31 <+bridge_> they allow you to release and press keys way easier than a normal mechanical keyboard 21:33 <+bridge_> I mean if it doesn't have any advantage why does it matter that it's not allowed 21:34 <+bridge_> snaptap? 21:34 <+bridge_> Yeah 21:37 <+bridge_> most modern keyboards ship with the feature either on by default or an option to enable and personally after using it the game felt way more responsive, and also alot of players use it and none of them get banned for using it so it doesnt even feel like its banned 21:37 <+bridge_> idk why people say its banned but no one ever gets banned for using it 21:37 <+bridge_> idk why people say its banned but no one ever gets banned for using it so might aswell just allow it 21:38 <+bridge_> Cannot connect to host master1.ddnet.org:443 ssl:default [getaddrinfo failed] 21:38 <+bridge_> who know this problem ? 21:38 <+bridge_> the only bans i have seen which was on block but they can just argue and say they are playing on controller and there is no way to prove they are cheating 21:38 <+bridge_> the only bans i have seen which was on block but they can just argue that they are playing on controller and there is no way to prove they are cheating 21:38 <+bridge_> idk why ppl say tas are banned yet leaderboard filled with tas runs so might as well just allow tas 21:38 <+bridge_> but people get banned for tas 21:39 <+bridge_> litteraly no one on ddrace has ever been banned for snaptap 21:39 <+bridge_> and you cant ban for it because they could be playing on controller 21:39 <+bridge_> @pioooooo @alw5 guys pls dont fight for me 21:39 <+bridge_> :)idk the problem 21:39 <+bridge_> Cannot connect to host master1.ddnet.org:443 ssl:default [getaddrinfo failed] 21:39 <+bridge_> look this problem 21:39 <+bridge_> devs 21:39 <+bridge_> (pls) 21:40 <+bridge_> You can also write macro that release lmb when holding rmb stuff and nobody would ban you 21:40 <+bridge_> check if you can open in browser https://master1.ddnet.org/ddnet/15/servers.json 21:41 <+bridge_> and if it isnt an advantage then why should it beanned 21:41 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486827446165573672/image.png?ex=69c6eb77&is=69c599f7&hm=22b88f511144335fe894fa2a609a4d60331f8c9faa1c5a1cfcac5b5abae9ea95& 21:41 <+bridge_> You felt game more responsive and that does sound advantage through input manipulation to me 21:42 <+bridge_> hey pioooo what happened 21:42 <+bridge_> and the game will feel more responsive if you get a better monitor or mouse 21:42 <+bridge_> bro 21:42 <+bridge_> idk then 21:42 <+bridge_> thx 21:43 <+bridge_> the game feeling more responsive shouldnt be a issue it should be a positive 21:43 <+bridge_> Plz don't ignore input manipulation part 21:43 <+bridge_> maybe look my ss ? 21:45 <+bridge_> admin kick always now 21:46 <+bridge_> i dont like him :) 21:46 <+bridge_> btw joking 21:46 <+bridge_> ily 21:46 <+bridge_> Are you using DDNet client? 21:46 <+bridge_> yes 21:46 <+bridge_> Is this in your console? 21:47 <+bridge_> no 21:47 <+bridge_> my discord bot 21:47 <+bridge_> terminal 21:47 <+bridge_> Uh so it's your bot's issue not game client 21:47 <+bridge_> maybe 21:47 <+bridge_> xd 21:48 <+bridge_> Then how should I know what's the issue :nouis: 21:48 <+bridge_> I wrote it yourself? 21:48 <+bridge_> U wrote it yourself? 21:49 <+bridge_> I thought the problem was with the URL because everything else in the code was working correctly. 21:49 <+bridge_> ye 21:49 <+bridge_> i remember making a snaptap like bind im gonna go remake it so i can argue that its already possible 21:49 <+bridge_> i remember making a snaptap like bind im gonna go remake it so i can argue that its already possible so isnt input modification in a way that the ddnet client doesnt support 21:50 <+bridge_> i remember making a snaptap like bind im gonna go remake it so i can argue that its already possible so it isnnt input modification in a way that the ddnet client doesnt support 21:50 <+bridge_> What do you use to make the https call .. what language what lib... 21:50 <+bridge_> Just vibe it :justatest: 21:51 <+bridge_> If that's the case I think there won't be reason to ban any more, but I doubt you can do that 22:00 <+bridge_> right.cfg 22:00 <+bridge_> ``` 22:00 <+bridge_> +left 22:00 <+bridge_> bind d "+right;exec right.cfg" 22:00 <+bridge_> bind a "+left;exec left.cfg" 22:00 <+bridge_> ``` 22:00 <+bridge_> left.cfg 22:00 <+bridge_> ``` 22:00 <+bridge_> +right 22:00 <+bridge_> bind d "+right;exec binds/tas/right.cfg" 22:00 <+bridge_> bind a "+left;exec binds/tas/left.cfg" 22:00 <+bridge_> ``` 22:00 <+bridge_> it isnt the exact same as snaptap but it does the same action of "manipulating your input and releasing the other key" 22:00 <+bridge_> So you mean it's not snaptap 22:01 <+bridge_> it releases the other direction like snaptap 22:02 <+bridge_> actually i just got an idea 22:02 <+bridge_> i migth be able to make full snaptap 22:03 <+bridge_> Bind master cooking 22:03 <+bridge_> it releases the other direction like snaptap where if eg 22:03 <+bridge_> you hold d then you hold a you will move left but then if you release a you wont move right like how snaptap works 22:12 <+bridge_> nvm it didnt work 22:12 <+bridge_> but this is the same action as snaptap just isnt as viable 22:13 <+bridge_> if u can make a bind that gives me hammer on lmb and switches back to weapon automatically i will be forever in ur debt 22:13 <+bridge_> isnt that already a thing? 22:13 <+bridge_> it is but it only gets back to weapon with rmb so hook 22:14 <+bridge_> i think i can but im playing rn 22:14 <+bridge_> ill try later 22:22 <+bridge_> Have anyone looked into the "chatresp" part in the (chat) messaging system 22:22 <+bridge_> I think it's kind of not intuitive and overcomplicated since it lead system chat functionality deep to the /base part then turn around to the function in the same class 22:22 <+bridge_> Not to speak this screenshot of the code contain 3 different way to do this, each do it in its own way 22:22 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486837850736689162/image.png?ex=69c6f527&is=69c5a3a7&hm=3d4c0098ffbb1dbb00bc54d34c9fe663e46edf61059cd27b9ab06b9dc8b2085f& 22:24 <+bridge_> I tried to look into the log.cpp part, but the thread-safe or the async or whatever part made me eventually unable to proceed understanding since there were too many implement of interfaces scattered all around the codebase 22:25 <+bridge_> And I asked AI about it, it give me this diagram 22:25 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486838496252657756/image.png?ex=69c6f5c1&is=69c5a441&hm=85d377ecf982c0f506fe6bc6714a95568a0c944cee3916e576f6267cf43c92c8& 22:26 <+bridge_> ```cpp 22:26 <+bridge_> str_format(aBuf, sizeof(aBuf), "The Server Timeout is currently set to %d seconds", g_Config.m_ConnTimeout); 22:26 <+bridge_> log_info("chatresp", "%s", aBuf); 22:26 <+bridge_> ``` 22:26 <+bridge_> pattern is also weird. These occurrences can be refactored to 22:26 <+bridge_> ```cpp 22:26 <+bridge_> log_info("chatresp", "The Server Timeout is currently set to %d seconds", g_Config.m_ConnTimeout); 22:26 <+bridge_> ``` 22:26 <+bridge_> `CClientChatLogger` is the relevant part of this `chatresp` system 22:26 <+bridge_> I know 22:27 <+bridge_> i think it's a more expressive name for what ends up happening in ddnet 22:27 <+bridge_> I looked into it and found it just lead back to SendChatTarget 22:27 <+bridge_> since contrary inputs are already allowed 22:27 <+bridge_> This is what I think, although I'm certainly unexperienced 22:27 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486839146084302918/81f0e30ce393b87c97729a476e9d8f66.png?ex=69c6f65c&is=69c5a4dc&hm=95977c2ff0f90561899aa64c09410ece782dd082853c14fd7e23e3495bce5581& 22:28 <+bridge_> i think putting marketing terms (SOCD, snaptap) into ddnet feels ugly 22:29 <+bridge_> But at least the implement can contain the actual logic in less complexity 22:31 <+bridge_> I don't know why some chat message are sent via the `chatresp` system while other just use `SendChatTarget` directly 22:31 <+bridge_> There also have a `CGameContext::SendChat`, that seems doing it more intuitive 22:31 <+bridge_> I don't know why some chat messages are sent via the `chatresp` system while other are sent with `SendChatTarget` directly 22:34 <+bridge_> `SendChatTarget` doesn't contain a log part (seemingly), but it was a few line of code 22:34 <+bridge_> `SendChatTarget` doesn't contain a log part (seemingly), but it was a few line of code to make it contain 22:34 <+bridge_> `SendChatTarget` doesn't contain a log part (seemingly), but it is just a few line of code to make it contain 22:35 <+bridge_> which ai can generate this based on code? 22:35 <+bridge_> Messages to individual players are probably not supposed to be logged generally 22:36 <+bridge_> Actually... 22:36 <+bridge_> https://deepwiki.com/search/whats-the-process-of-the-chat_ab904ce3-026a-4c5b-a36a-d75a93d682e4?mode=deep 22:37 <+bridge_> thanks 22:37 <+bridge_> So there's a SendChat(...) 22:39 <+bridge_> There's also log stuff but much much better, that readers can just leave it alone and continue to the main logic rather than forced to dive into the log part to finally see the main logic in the SendChatTarget 22:39 <+bridge_> https://cdn.discordapp.com/attachments/293493549758939136/1486842067559776277/image.png?ex=69c6f915&is=69c5a795&hm=48f2037a34feac617ac6d8c97f9ae50e34d9a1cf8f10f73a3a1489bfd95a4ed3& 22:56 <+bridge_> @robyt3 should I pin xcode/sdk version on ci? 22:57 <+bridge_> Seems better for reproducibility and so the build doesn't break when the latest version is updated 23:27 <+bridge_> furo can you please add regex search for player/map names? on ddstats? 23:27 <+bridge_> i need it urgently right now