Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seek in temporary blob level 0 makes read return wrong data #7422

Closed
asfernandes opened this issue Dec 13, 2022 · 3 comments · Fixed by #7424
Closed

Seek in temporary blob level 0 makes read return wrong data #7422

asfernandes opened this issue Dec 13, 2022 · 3 comments · Fixed by #7424

Comments

@asfernandes
Copy link
Member

Without line blob->seek(&status, 0, 0); data is returned correctly.

#include "ifaceExamples.h"
#include <firebird/Message.h>

static IMaster* master = fb_get_master_interface();

static void errPrint(IStatus* status)
{
	char buf[256];
	master->getUtilInterface()->formatStatus(buf, sizeof(buf), status);
	fprintf(stderr, "%s\n", buf);
}

static void drop(IAttachment** att)
{
	// With CheckStatusWrapper passed as status interface noting is thrown on error
	// You should check status yourself
	CheckStatusWrapper status(master->getStatus());

	// drop database (will close interface)
	(*att)->dropDatabase(&status);
	if (status.getState() & IStatus::STATE_ERRORS)
	{
		errPrint(&status);
		fprintf(stderr, "*** Drop database failed - do it manually before next run ***\n");
	}
	else
		*att = nullptr;

	// cleanup
	status.dispose();
}

int main()
{
	int rc = 0;

	// set default password if none specified in environment
	setenv("ISC_USER", "sysdba", 0);
	setenv("ISC_PASSWORD", "masterkey", 0);

	// With ThrowStatusWrapper passed as status interface FbException will be thrown on error
	ThrowStatusWrapper status(master->getStatus());

	// Declare pointers to required interfaces
	IProvider* prov = master->getDispatcher();
	IAttachment* att = nullptr;
	ITransaction* tra = nullptr;
	IBlob* blob = nullptr;

	try
	{
		att = prov->createDatabase(&status, "blob_test.fdb", 0, nullptr);
		tra = att->startTransaction(&status, 0, nullptr);

		FB_MESSAGE(Msg, ThrowStatusWrapper,
			(FB_BLOB, b)
		) message(&status, master);

		message.clear();
		att->execute(&status, tra, 0, "select blob_append(null, '1234567890') from rdb$database", SAMPLES_DIALECT,
			nullptr, nullptr, message.getMetadata(), message.getData());
		blob = att->openBlob(&status, tra, &message->b, 0, nullptr);

		blob->seek(&status, 0, 0);

		int bufOver = 0;
		for (bool eof = false; !eof; )
		{
			const char* lineFeed = "\n";
			char buf[3];
			unsigned l = 0;

			switch (blob->getSegment(&status, sizeof(buf) - 1, buf, &l))
			{
				case IStatus::RESULT_OK:
					break;
				case IStatus::RESULT_SEGMENT:
					lineFeed = "";
					bufOver++;
					break;
				default:
					eof = true;
					continue;
			}

			buf[l] = 0;
			printf("%s%s", buf, lineFeed);
		}

		blob->close(&status);
		blob = nullptr;

		tra->commit(&status);
		tra = nullptr;

		drop(&att);
	}
	catch (const FbException& error)
	{
		// handle error
		rc = 1;
		errPrint(error.getStatus());

		if (att)
			drop(&att);
	}

	// release interfaces after error caught
	if (blob)
		blob->release();

	if (tra)
		tra->release();

	if (att)
		att->release();

	status.dispose();
	prov->release();

	return rc;
}
@hvlad
Copy link
Member

hvlad commented Dec 13, 2022

BLOB_APPEND have nothing comon with this test.
Just replace it by base64_encode(cast('1234567890' as blob sub_type text)).

@aafemt
Copy link
Contributor

aafemt commented Dec 13, 2022

That would produce a segmented BLOB, no? Seek is supposed not to work with segmented BLOBs at all.

@hvlad
Copy link
Member

hvlad commented Dec 13, 2022

No.
Why do you think I use base64_encode ?

@asfernandes asfernandes changed the title Seek in blob created with BLOB_APPEND makes read return wrong data Seek in temporary blob makes read return wrong data Dec 14, 2022
@asfernandes asfernandes self-assigned this Dec 14, 2022
@asfernandes asfernandes changed the title Seek in temporary blob makes read return wrong data Seek in temporary blob level 0 makes read return wrong data Dec 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment