Login
Channel Apps
Channel About Photos Files Calendar
System Apps
Directory Help Language Public Stream Random Channel Report Bug Search
Please read the Code of Conduct that applies for this forum:
Click to open/close

The Code of Conduct of Hubzilla.org (Version 22 June 2024)

In all publications and interactions on Hubzilla.org, we ask you to cultivate and demand respectful interaction with one another and to be aware of the consequences of your actions (in relation to the world and the future).

Your'e asked to behave in a way that enables all users and visitors of Hubzilla.org to participate (to inform, to get informed, to discuss, to develop, to create) without harassment, regardless of age, body size, disability, ethnicity, gender characteristics, gender identity and expression, level of experience, education, social status, nationality, personal appearance, race, caste, skin colour, religion or sexual identity and orientation.
We ask you to act and interact in a way that contributes to an open, welcoming, diverse, inclusive and healthy community.

These are examples of behaviours that contribute to a positive environment for the community:
  • Show empathy and kindness towards everyone
  • Respect different opinions, points of view and experiences
  • Give constructive feedback
  • Accept constructive feedback with dignity
  • Take responsibility
  • Apologise to those affected by your mistakes
  • Learn from experience
  • Focus on what is best not only for you as an individual, but for the community as a whole

The following behaviour will result in your channel being blocked:
  • You use sexualised language, images or symbolism
  • You make an unwanted sexual advance
  • You make offensive or derogatory comments
  • You attack someone personally or politically
  • You engage in trolling
  • You harass someone, whether publicly or privately
  • You publish other people's private information without their express permission
  • You display behaviour that could reasonably be considered inappropriate in a professional environment

The board of directors of the Hubzilla Association will remove posts and comments that do not comply with this Code of Conduct and block their author.

This Code of Conduct applies to all content published in a channel which is hosted on hubzilla.org, even if the channel is a private one (a closed circle).
MIME type detection in include/attach.php

Hubzilla Development
development@hubzilla.org
Der Pepe (Hubzilla) ⁂ Der Pepe (Hubzilla) ⁂ wrote the following post 2026年8月22日 13:09:29 +0200

MIME type detection in include/attach.php

I would like to open up for discussion the function currently used to determine the MIME type in include/attach.php.

In my view, relying solely on finfo() is inadequate.

finfo() uses the libmagic library to determine the MIME type. This works fairly reliably for files in binary formats, as such files usually begin with specific byte sequences. However, libmagic is very unreliable when it comes to text files. This is not a criticism – I wouldn’t know of any way to improve the detection of text formats in libmagic either – but is down to the way the library works.

To determine the MIME type, libmagic analyses the file itself and ignores the file extension. Whilst this works well for binary formats due to specific byte sequences, the detection of text formats is almost impossible, or at least very unreliable. It searches for specific text patterns. And if no truly unambiguous recognition takes place here (because, for example, patterns from two or more different text formats occur in the file, or the required patterns are not present), then "text/plain" is returned as the result.

Markdown example: I write quite a few guides or help texts for Hubzilla. Usually in Markdown format. If I write an article on using stylesheets, the Markdown text also contains sequences that are CSS (as examples, for explanation, etc.). libmagic recognises that it is probably a Markdown document because it detects patterns characteristic of this format. But unfortunately, it also recognises that it’s probably a CSS file because it detects patterns typical of that format... and if I also explain JavaScript in the text, it finds patterns that indicate a JS file as well. The recognition is inconsistent and (understandably and correctly) libmagic falls back on the assumption that it is definitely a text file and returns "text/plain" for my file, which is actually "text/markdown".

And this is what happens with all text files.

Furthermore, the pattern recognition is apparently quite simple and rigid. For instance, shell files are only recognised as "text/x-shellscript" if they begin with a shebang. If this is missing, but the file is clearly a shell script and even has the .sh extension, then libmagic (and consequently finfo) returns "text/plain" as the MIME type.
PHP is rigidly recognised by "<?php" or "<?" immediately at the start, whilst JavaScript is strictly recognised by "function", "class", "import", "export" or "//" at the start.

I’ve tested this for a number of text formats using my test script and confirmed issues with

CSS: text/css
Markdown: text/markdown
TOML: application/toml
sh: text/x-shellscript
PHP: text/x-php
TeX: application/x-tex
js: text/javascript
html/htm: text/html
XML: text/xml
JSON: application/json

If the exact matching patterns (usually required at the start of the file) are not present, you get ‘text/plain’. Incidentally, with CSS, I managed to get the recognition to work without any pattern at all. ;-)

This means that when uploading text documents, the wrong MIME type is almost always stored in the ‘filetype’ field. This usually has no consequences. However, if a client requests and evaluates the MIME type, it can lead to errors (such as when using custom stylesheets).

Generally speaking, determining the MIME type using `finfo()` is a good decision, and it works very well with binary files. However, the shortcomings with text formats need to be addressed urgently. It’s not exactly rocket science. If finfo() returns "text/plain" as the result, then for the problematic file types, detection based on the file extension should simply be used instead. At least for text file extensions that aren’t reliably recognised by libmagic. I don’t see this as a real security risk either.

Suggestion:

  // Until here we either used the provided mime type or set mimetype by extension.
// Both variants are inherently unsafe hence try to find and set the real mimetype before storage.

if (class_exists('finfo') && is_file($os_basepath . $os_relpath)) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimetype = $finfo->file($os_basepath . $os_relpath);

if ($mimetype === false) {
$mimetype = 'application/octet-stream';
}

// A fallback for libmagic, which often incorrectly identifies certain text files as ‘text/plain’
if ($mimetype === 'text/plain') {
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

$mime_fix_map = [
'css' => 'text/css',
'js' => 'text/javascript',
'html'=> 'text/html',
'htm' => 'text/html',
'xml' => 'text/xml',
'json'=> 'application/json',
'md' => 'text/markdown',
'php' => 'text/x-php',
'toml" => 'application/toml',
'tex' => 'application/x-tex',
'sh' => 'text/x-shellscript'
];

if (isset($mime_fix_map[$extension])) {
$mimetype = $mime_fix_map[$extension];
}
}
}

@Harald Eilertsen @Mario Vavti @Alfred Bühler

Mario Vavti
mario@hub.somaton.com
IIRC there is no need to determine the mimetype again, we have already looked at the headers and extension before attempting finfo().

Both, headers and extension, are easy to manipulate hence we rely on finfo(). IMO we should only fall back to header/extension based mimetype if the uploader has code rights.
Alfred Bühler
abu@hub.alfredbuehler.ch
@Hubzilla Development To serve as a general-purpose WebDAV service, we shouldn't tweak the MIME type at all. But for my sake, we can swipe off any exec attributes
Proposed Policy for generative "AI" use in the Hubzilla project

Hubzilla Development
development@hubzilla.org
Harald Eilertsen Harald Eilertsen wrote the following post 2026年8月13日 13:44:26 +0200

Proposed Policy for generative "AI" use in the Hubzilla project

A heads up to everyone!

We are proposing a new policy with regards to how LLM's and other "AI" systems can be used with regard to the Hubzilla code base. As this is a pretty significant policy update, I think it's vital that we, the community, get some time to discuss and provide feedback on the change.

The MR introducing this change can be found here:
https://framagit.org/hubzilla/core/-/merge_requests/2320

Thanks!

- - -
Mario Vavti
mario@hub.somaton.com
Just found out about the NLnet GenAI policy: https://nlnet.nl/foundation/policies/generativeAI/

TL;DR: they basically allow usage with full disclosure of model, prompts and a log thereof. Also one has to make sure the outcome can be legally distributed as FOSS etc.

I seriously wonder if that is even possible thinking_face
Der Pepe (Hubzilla) ⁂
pepecyb@hub.hubzilla.hu
Mario Vavti
mario@hub.somaton.com
What about 3rd party libraries we rely on?
Channel Creation Wizard

Hubzilla Development
development@hubzilla.org
Der Pepe (Hubzilla) ⁂ Der Pepe (Hubzilla) ⁂ wrote the following post 2026年8月06日 14:24:14 +0200

Channel Creation Wizard

@Mario Vavti @Harald Eilertsen

With his Solidified theme, Saiwal has developed a channel creation wizard that makes onboarding – and indeed simply creating a channel – incredibly straightforward, and represents a real boost to the user experience.

Please have a look here:

#^https://hub.hubzilla.hu/articles/pepecyb/create-channel

I think that an identical wizard as a general replacement for the previous channel creation dialogue would be extremely useful and desirable. However, in the step where the theme style is selected, a list of themes should appear, showing all themes activated on the hub, with the default theme – the one selected by the admin in the admin panel – preselected. For Solidified, the colour scheme could also be available for selection at this point, provided it has been chosen as a theme by the user. Saiwal would then also need to incorporate the theme selection into his wizard at this point.

What do you think of the idea in principle? It’s clear that the wizard would need to replace the current code for the simple form using PHP.

I’m not concerned here with the implementation, but rather with whether this would generally be desired and accepted before anyone sets to work on it.

Harald Eilertsen
harald@hub.volse.no
@Der Pepe (Hubzilla) ⁂ Personally I think this would be a great idea.
Hubzilla Development
development@hubzilla.org
Mario Vavti Mario Vavti wrote the following post 2026年7月27日 09:08:31 +0200
We might be able to outsource HTTP Message Signatures in the near future slightly_smiling_face

daniel:// stenberg:// daniel:// stenberg:// wrote the following post 2026年7月27日 08:55:21 +0200

PDO Prepared Statements

Hubzilla Development
development@hubzilla.org
Mario Vavti Mario Vavti wrote the following post 2026年7月19日 08:55:33 +0200

PDO Prepared Statements

Currently we use q() to access the data. This uses PDO::query() directly which has slightly less overhead compared to prepared statements but also has its drawbacks. We have to escape the arguments manually and repetitive queries have a slightly lower performance.

I would like to introduce 3 new functions:
- p() for preparing a statement.
- e() for executing the prepared statement.
- pe() combining p() and e() to successively replace the currently used q() function.

What do you think?

Harald Eilertsen
harald@hub.volse.no
I'm wondering if it would be better to just use PDO directly. The PDO object handle is available today via DBA::$dba->db which is a bit clumsy, but perhaps add a shortcut like DBA::db(), App::db(), a singleton, or even just a global $hzdb object?

Unless we really need a layer between us and PDO, I'm not sure it's worth maintaining one.

One example of where having a layer between is useful is the DBA::$dba->insert() function. It returns the inserted row without the calling code having to care which DB it's connected to. (MySQL don't support the RETURNING clause, but Postgres and MariaDB do.)

However, if we're moving toward a more entity based architecture, this kind of logic may be better implemented there?

In any case, I think I would prefer an object based interface. Something like:

$stmt = $db->prepare(...);
$stmt->execute(...);

Instead of single letter function names in the global namespace.

Btw, one additional advantage of using PDO directly, is that it can populate objects for us directly: See PDO::FETCH_CLASS and PDOStatement::fetchObject.

This could be very handy when moving to entity classes.
Mario Vavti
mario@hub.somaton.com
Entity/Repository Model for Hubzilla

Hubzilla Development
development@hubzilla.org
Mario Vavti Mario Vavti wrote the following post 2026年7月17日 17:00:42 +0200

Entity/Repository Model for Hubzilla

Some time ago we discussed how to proceed with refactoring/modernizing the Hubzilla codebase. AFAIK we came to the conclusion that the Entity/Repository model would be the most suitable to convert to. Please correct me if i am wrong @Harald Eilertsen.

I think it would be good to have some sample code where devs (like me) will be able to look at to get this going.

I think i might be able to start with something but will sure need some help slightly_smiling_face

- - -
Mario Vavti
mario@hub.somaton.com
Trying to build a Xchan entity based on the structure of the Addon example. Let's see how this goes slightly_smiling_face
Mario Vavti
mario@hub.somaton.com
@Harald Eilertsen what would be best practice constructing an entity where we might not have all the data yet? Is it acceptable to provide default values in the constructor?

E.g. when storing an actor we do not have its local profile image url yet because the image is fetched and processed later via a Daemon.
Mario Vavti
mario@hub.somaton.com
Another question to make sure i understand things correctly:

Basically we want to check/sanitize the data in some sort of save or store method and only build the object after it is stored. We do not want to do this during construct and we also do not want to be able to construct an entity from outside the class. Right?
Federation with lemmy communities breaking due to user agent identifying as browser.

Hubzilla Development
development@hubzilla.org
Saiwal Saiwal wrote the following post 2026年7月13日 11:38:06 +0200

Federation with lemmy communities breaking due to user agent identifying as browser.

my replies were being rejected by lemmy.world because they were identified as coming from a browser due to the user agent being `Mozilla/5.0 (compatible; zot)` and were presented with a challenge.
In discussion with lemmy.worlds admin it was suggested that hubzilla should use its url in user agent.

- - -
Mario Vavti
mario@hub.somaton.com
Here are some examples...
Friendica:
Friendica/2026.05 DatabaseVersion/1595 Request/ActivityPub/1 +https://host.tld

Mastodon:
Mastodon/4.5.11 (http.rb/5.3.1; +https://host.tld/)

Peertube:
PeerTube/8.2.2 (+https://host.tld)

I like the peertube one because it does not overshare information.
Der Pepe (Hubzilla) ⁂
pepecyb@hub.hubzilla.hu
@Hubzilla Development @Mario Vavti @Saiwal

Changing the user agent is a nice idea and can certainly make sense. But let’s look at the bigger picture:
It doesn’t change the actual problem. Suppose I change the user agent string so that it works with instance "A"; that, however, means it won’t work with instance "B" using that string, which expects a different string – which in turn won’t work with instance "C"...

How are we supposed to deal with that? Where will it end? "Floating user agent strings"?

You’ll never get to grips with this "gatekeepers against AI bots" nightmare this way. Anyone who puts their Fediverse server behind such a barrier has to accept that their instance is no longer fully integrated into the Fediverse.
Nested reshare beyond second level possible?

Hubzilla Development
development@hubzilla.org
Saiwal Saiwal wrote the following post 2026年7月11日 03:50:09 +0200

Nested reshare beyond second level possible?

when i make a post and reshare it the first post gets embedded within the subsequent post as [share=][/share] but there is no share option on this second post.
Is there a technical reason why nested reshares cannot be done?

Saiwal
sk@utsukta.org
asking because i was trying multilevel reshare with my theme and with activitypub enabled it was producing corrupted RE: ..... url due to matching the first [share] block with the first [\share] and other levels get ignored.
Mario Vavti
mario@hub.somaton.com
Outbound nested reshares are not yet implemented. I don't mind them but question their usefulness person_shrugging
Cleaning up missing return statements in functions

Hubzilla Development
development@hubzilla.org
Harald Eilertsen Harald Eilertsen wrote the following post 2026年7月09日 12:43:16 +0200

Cleaning up missing return statements in functions

For a while I've been using PHPStan to go through and fix functions in core that are expected to return a value, but that has code paths where no value would be returned. However, there's a few functions left that I don't really know what to do about.

These are the following:

------ ------------------------------------------------------------------------------------------------ 
Line Zotlabs/Module/Pdledit_gui.php
------ ------------------------------------------------------------------------------------------------
190 Method Zotlabs\Module\Pdledit_gui::get() should return string but return statement is missing.
🪪 return.missing
------ ------------------------------------------------------------------------------------------------

------ ----------------------------------------------------------------------------------------------------------------
Line Zotlabs/Storage/Browser.php
------ ----------------------------------------------------------------------------------------------------------------
434 Method Zotlabs\Storage\Browser::generateDirectoryIndex() should return string but return statement is missing.
🪪 return.missing
------ ----------------------------------------------------------------------------------------------------------------

------ ------------------------------------------------------------------------------------------
Line Zotlabs/Storage/File.php
------ ------------------------------------------------------------------------------------------
286 Method Zotlabs\Storage\File::get() should return string but return statement is missing.
🪪 return.missing
------ ------------------------------------------------------------------------------------------

[ERROR] Found 3 errors

It would be nice if we could get these in shape as well, so that we can enable this PHPStan test by default. That would help us catch such mistakes as they happen in the future, instead of having to clean up a bunch of them later.

Expert mode of "Inspect queue"

Hubzilla Development
development@hubzilla.org
Der Pepe (Hubzilla) ⁂ Der Pepe (Hubzilla) ⁂ wrote the following post 2026年7月04日 18:06:35 +0200

Expert mode of "Inspect queue"

I can understand your concerns regarding the expert mode of "Inspect queue", @Mario Vavti .

I do think, however, that an admin should know what they’re doing when they delete entries from outq. A warning to that effect could certainly be included in the template, if it seems necessary.

In my view, automatically flagging a hub as offline if it has been unreachable for a long time seems a bit unreliable. For example, zotlabs.org has been permanently (!) unreachable for more than half a year now. Nevertheless, entries for zotlabs.org kept appearing in my queue, only to disappear again after a few delivery attempts. However, the hub was not marked as permanently offline (DB: `site` WHERE site_dead = 1), and entries for that hub kept reappearing. It was only by explicitly marking it using the button in expert mode that the value was entered into field 1.

The fundamental question (regardless of whether a hub is marked as permanently offline automatically after a certain period, or by explicitly marking it in expert mode) is: what happens if such a hub becomes accessible again after a long period of time? Is it, if necessary, marked as available again in some way? Otherwise, I would say there ought to be a module for the admin that displays the hubs marked as offline and, if necessary, allows them to be removed from this list.

Mario Vavti
mario@hub.somaton.com
I do think, however, that an admin should know what they’re doing when they delete entries from outq.

We have had a different experience, hence the expert mode.

In my view, automatically flagging a hub as offline if it has been unreachable for a long time seems a bit unreliable.

In this case we should make it reliable. zotlabs.org is a special case because it never ever returns a HTTP code.

The fundamental question (regardless of whether a hub is marked as permanently offline automatically after a certain period, or by explicitly marking it in expert mode) is: what happens if such a hub becomes accessible again after a long period of time?

AFAIK it will be marked alive again as soon as we get a message from it.

AltStyle によって変換されたページ (->オリジナル) /