HN user

joecarpenter

328 karma

http://mrjoes.github.io/

Posts4
Comments21
View on HN

Great analysis!

The Go binary was also compromised, but there's almost no information what the compromised binary did. Did it drop a python script? Did it do direct scanning?

If trivy docker image was used, what's the scope (it does not include python).

In my case I'm decompiling into C and it does a pretty good job at translation. There were situations where it missed an important implementation detail. For example, there is an RLE decompressor and Gemini generated plausible, but slightly incorrect code. Gemini 3 Pro was not able to find the bug and produced code that was similar to Gemini 3 Flash.

The bug was one-shotted by GPT 5.2.

Reverse engineering with LLMs is very underrated for some reason.

I'm working on a hobby project - reverse-engineering a 30 year old game. Passing a single function disassembly + Ghidra decompiler output + external symbol definitions RAG-style to an agent with a good system prompt does wonders even with inexpensive models such as Gemini 3 Flash.

Then chain decompilation agent outputs to a coding agent, and produced code can be semi-automatically integrated into the codebase. Rinse and repeat.

Decompiled code is wrong sometimes, but for cleaned up disassembly with external symbols annotated and correct function signatures - decompiled output looks more or less like it was written by a human and not mechanically decompiled.

Isn't it the opposite? From the link: Scores range from -100 to 100, where 0 means as many correct as incorrect answers, and negative scores mean more incorrect than correct.

Gemini 3 Flash scored +13 in the test, more correct answers than incorrect.

Ah, the memories! Around the fall of the Soviet Union, there was an IBM-compatible clone called Poisk. It was not 100% compatible with with IBM PC, had 128 KB built-in RAM (extensible to 640 KB with a card), had CGA graphics with a composite output only, no floppy interface without an addon, etc. But it was cheap, like really cheap and only needed a TV and a tape recorder to get going. I'd say Poisk was #2 home PC after gazillion of inexpensive ZX Spectrum clones.

Article mentions that tape interface was rarely used - that was definitely not the case in the (ex)USSR.

Anyway, having spent so much time with Poisk with cassette interface after ZX Spectrum, I can still distinguish PC vs ZX tapes by just listening to them - they have slightly different tonality.

They're being used side by side and running in separate processes.

For Campus Bubble, tornado app is a relatively simple push broker. Whenever something happens, Flask app pushes notification to a broker and broker pushes them in fan-out fashion to subscribers.

I even wrote another blog post a while ago about possible approach: http://mrjoes.github.io/2013/06/21/python-realtime.html

There were requests to create read-only views, but they're domain specific and can be done with existing machinery.

Unfortunately, you can't compare development frameworks to UI frameworks. No one knows that you're a dog on the Internet. But anyone without technical knowledge can see a site that's built with the default Bootstrap skin and say - hey, I saw it before.

Bootstrap is good and clean framework, it is _great_ for developers. But just because it is so widespread and highly visible, there's some of prejudice around it.

Nonetheless, I'm using Bootstrap in my projects and happy with it.

Uh, that's typical rhetoric about default Bootstrap interface. Like if someone used default bootstrap skin then he's just lazy and didn't really care. Thus unprofessional.

Personally, I think that Bootstrap interface is good enough, but its widespread adoption lead to the perception I mentioned above.

Flask-AppBuilder is opinionated fork of the Flask-Admin. It follows similar conventions and uses some of the Flask-Admin code, but comes up with non-default skin and a little more batteries (like user management interface out of the box). If compared directly, existing Flask-Admin components are much more featureful that their counterparts in the Flask-AppBuilder.

Flask-AppBuilder API is not compatible with vanilla Flask-Admin APIs, so you won't be able to exchange components between them. And sure, you can build something similar to Flask-AppBuilder on top of Flask-Admin without changing its core. Or maybe someone already built it (like Flask app skeleton with built-in administrative interface).

I explained reasoning behind default Bootstrap skin and lack of built-in user management in the blog post.

I have nothing against forks, it is good to have multiple options to choose from.

It is mostly number of documents and their size. Single schema.

There are no indexes, so whenever client wants to find something in synchronized collection, it'll have to scan through all documents. With 10k documents it was locking up DOM (it was very noticable).

If documents are large, client won't be able to connect to the server with any of the polling transports - initial synchronization time exceeds 30 seconds and SockJS will drop connection. This is partially solvable by having reverse-caching proxy (i.e. nginx) forcibly compress all polling SockJS responses.

Started using the SmartCollections package which ditches polling altogether and goes with the MongoDB OPLOG for synchonization.

Yes, I'm aware about this package. However, in my case, I had to reactively count number of items in collection. SmartCollections does not have `observe` for server-side cursors and core Collection implementation is slow, so I decided to use `setTimeout` to check collection size every few seconds, which turned out to be much faster than generic collection implementation.

The key thing is you really shouldn't expect to do many MB's of client data storage in your app.

True, it just contradicts point 003 on http://www.meteor.com/

Plus, I was also referring server-side. Application does not work with node.js MongoDB driver, it still goes through thin minimongo layer, which hides most of the driver API. And it is not fast either (due to reactivity) - see insert performance example.

Overall, I don't say it is not possible to run Meteor app in production (I have one). It is just there are alot of different quirks and gotchas in Meteor that should be worked out manually or with help of community-created packages. And all this information is mostly scattered around StackOverflow, Meteor bugtracker or in Meteor source code itself.

It is quite unpleasant to stumble upon collection synchronization performance when you have most of the application in place.

Interesting enough, I found that Meteor is not production ready, in both current implementation (not mature) and some design decisions. I was thinking about writing blog post about it, but no idea when I'll have time to do it, so I decided to stop by.

I have experience with Meteor in production and had some serious performance-related problems. Not that they're not solvable, but some solutions kill some core design decisions of Meteor. Just in case - I didn't pick Meteor for the project, I was asked to help with it.

Anyway, here's short list:

1. Collection synchronization does not really work even for relatively small amounts of data (say 10k records).

- It does not make much sense to send few MB of initial data to the client. Paging API was moved to some distant future and you end up writing REST-like API on top of Meteor, which breaks idea of collection synchronization, which contradicts statement on their website - "no need to write REST APIs anymore". I don't say it is not usable at all, you just need to be really-really careful about what you send to client and it is easy to fail at this.

- SockJS (transport protocol used by Meteor) does not have rate-limiting built-in. If client connects using one of the polling transports and payload is too large to be received in 30 (? - vanilla SockJS uses 5) seconds, server drops connection thinking that client timed out. Partially, it is SockJS problem and partially it is Meteor problem, as Meteor will just send all outgoing data without caring if client is on slow connection. But because of previous point, generally it is bad idea to send large amount of data anyway.

- Server-side subscription API is very limited. Official documentation has following sample: reactively count number of admins in collection. This is done by listening on collection changes and counting admins by incrementing (when admin is added) and decrementing (when admin is removed) single variable. If there are 10k admins in database, increment function will be called 10k times.

2. Minimongo is interesting concept, but fails on many levels:

- It is MongoDB written in JS, but slow

- Does not have indexes ("client won't handle amounts of data for indexes to be viable"), aggregation, map reduce, etc. There's no official API to create index on server-side either.

- Its reactive - whenever model is changed, Meteor figures out which fields were changed and broadcasts changes to all listeners. And this is _not_ fast. Inserting 10k items to collection will take around 2 minutes on AWS large instance with node executable using 100% CPU.

- Because MongoDB is not "reactive", Meteor just polls collections every 5 seconds to see if they changed by outside application. I really hope it only tracks addition/deletion of records and not scanning through all rows in database during each polling iteration

- Meteor API is hiding MongoDB handle, but there's a way to get it (through hack) and use it directly. And it takes 3 seconds to insert same 10k items

3. Client-side is not as convenient as current MV* frameworks

- Meteor is using non-reactive templating engines and attempts to make them reactive. And this might be performance bottleneck, especially on mobile devices. When single variable changes, Meteor will re-render whole template. If you have some 3rd party plugins (like WYSIWYG editor, which injects own DOM markup), you have to wrap it with special blocks, which prevent Meteor from re-rendering them.

- As a result of previous point, DOM is not stable.

- Unlike AngularJS/Ember/etc, Meteor does not track individual variables. AngularJS does it by checking if variable changed in digest loop, Ember uses property-like system, etc. Meteor has global, flat namespace called "Meteor.session", where application stores _all_ reactive variables that can be referenced by their name. `Meteor.session.set('mymodule.hello', 10)`. It is hard to structure application, when core reactive part is just a singleton dictionary.

- Once you get used to bidirectional data binding between forms and models, it is hard to get away with events. But that's minor.

4. Overall architecture (nitpicking):

- Meteor API likes singletons. `Meteor.session`, `Meteor.methods`, `Meteor.templates`, etc. Single, flat namespaces everywhere

- Even though code can be written in a way it can run on both client and server, there are subtle core API differences. Like it is not possible to use `HTTP.get` on the client without callback, but it works on the server, just blocks the fiber. If you use callback on the server, you need to block the fiber manually (using future or fiber API), etc.

- No server-side templates. Yes, there's crawlable package for Meteor, but it is just PhantomJS (WebKit) that runs on the server and renders pages for crawlers. Yikes.

This pretty much sums my experience with Meteor.

Greenlets don't magically make synchronous libraries asynchronous! That's gevent!

That's right - I wrote that they allow writing code in synchronous fashion and I didn't say that it happens automagically though.

That might be true, but then you need to keep in mind that callbacks doesn't necessarily mean something-looking-like-the-Tornado-callback-demo-code.

Yep, I also provided how Futures and generator-based coroutines can be built on top of the callbacks.

Just in case, Tornado supports both out of the box.

The twisted equivalent of this wouldn't even look like data = yield get_more_data(); Twisted's API calls you when there's data, so it looks even simpler

Very similar to some Tornado API too - method of a class that gets called when something happens. For example, sockjs-tornado follows this convention.

- Twisted predates PEP-8's recommendation of snake_case ;-)

Yes, I'm aware of it, but before I started playing with asynchronous libraries, I had some Python experience and got used to underscore naming convention. While it is easy to switch between both, I'd prefer consistent code style. Especially when I mix typical Flask Web application with real-time portion in same application.

No doubt, Twisted is mature and featureful framework. When I was investigating different options, Twisted was first one I tried. However, I also tried Tornado and found it easier to start with. And because Tornado worked for me, I decided to stick to it.

I'm just sharing my personal experience with both. And no, I prefer Flask (WSGI) and Tornado working side by side, in separate processes.